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 ...
Unified · Split
| @@ -463,7 +463,7 @@ again without disrupting RCU readers. · 462 unmodified lines | |||
| 463 | This guarantee was only partially premeditated. DYNIX/ptx used an | 463 | This guarantee was only partially premeditated. DYNIX/ptx used an |
| 464 | explicit memory barrier for publication, but had nothing resembling | 464 | explicit memory barrier for publication, but had nothing resembling |
| 465 | ``rcu_dereference()`` for subscription, nor did it have anything | 465 | ``rcu_dereference()`` for subscription, nor did it have anything |
| 466 | resembling the ``smp_read_barrier_depends()`` that was later subsumed | 466 | resembling the dependency-ordering barrier that was later subsumed |
| 467 | into ``rcu_dereference()`` and later still into ``READ_ONCE()``. The | 467 | into ``rcu_dereference()`` and later still into ``READ_ONCE()``. The |
| 468 | need for these operations made itself known quite suddenly at a | 468 | need for these operations made itself known quite suddenly at a |
| 469 | late-1990s meeting with the DEC Alpha architects, back in the days when | 469 | late-1990s meeting with the DEC Alpha architects, back in the days when |
| @@ -93,6 +93,11 @@ It exists in the sparse memory mapping model, and it is also somewhat · 92 unmodified lines | |||
| 93 | similar to the mem_map variable, both of them are used to translate an | 93 | similar to the mem_map variable, both of them are used to translate an |
| 94 | address. | 94 | address. |
| 95 | 95 | ||
| 96 | MAX_PHYSMEM_BITS | ||
| 97 | ---------------- | ||
| 98 | |||
| 99 | Defines the maximum supported physical address space memory. | ||
| 100 | |||
| 96 | page | 101 | page |
| 97 | ---- | 102 | ---- |
| 98 | 103 | ||
| @@ -399,6 +404,17 @@ KERNELPACMASK · 300 unmodified lines | |||
| 399 | The mask to extract the Pointer Authentication Code from a kernel virtual | 404 | The mask to extract the Pointer Authentication Code from a kernel virtual |
| 400 | address. | 405 | address. |
| 401 | 406 | ||
| 407 | TCR_EL1.T1SZ | ||
| 408 | ------------ | ||
| 409 | |||
| 410 | Indicates the size offset of the memory region addressed by TTBR1_EL1. | ||
| 411 | The region size is 2^(64-T1SZ) bytes. | ||
| 412 | |||
| 413 | TTBR1_EL1 is the table base address register specified by ARMv8-A | ||
| 414 | architecture which is used to lookup the page-tables for the Virtual | ||
| 415 | addresses in the higher VA range (refer to ARMv8 ARM document for | ||
| 416 | more details). | ||
| 417 | |||
| 402 | arm | 418 | arm |
| 403 | === | 419 | === |
| 404 | 420 | ||
| @@ -28,6 +28,16 @@ Documentation/devicetree/bindings/iommu/iommu.txt. · 27 unmodified lines | |||
| 28 | For arm-smmu binding, see: | 28 | For arm-smmu binding, see: |
| 29 | Documentation/devicetree/bindings/iommu/arm,smmu.yaml. | 29 | Documentation/devicetree/bindings/iommu/arm,smmu.yaml. |
| 30 | 30 | ||
| 31 | The MSI writes are accompanied by sideband data which is derived from the ICID. | ||
| 32 | The msi-map property is used to associate the devices with both the ITS | ||
| 33 | controller and the sideband data which accompanies the writes. | ||
| 34 | |||
| 35 | For generic MSI bindings, see | ||
| 36 | Documentation/devicetree/bindings/interrupt-controller/msi.txt. | ||
| 37 | |||
| 38 | For GICv3 and GIC ITS bindings, see: | ||
| 39 | Documentation/devicetree/bindings/interrupt-controller/arm,gic-v3.yaml. | ||
| 40 | |||
| 31 | Required properties: | 41 | Required properties: |
| 32 | 42 | ||
| 33 | - compatible | 43 | - compatible |
| @@ -49,11 +59,6 @@ Required properties: · 15 unmodified lines | |||
| 49 | region may not be present in some scenarios, such | 59 | region may not be present in some scenarios, such |
| 50 | as in the device tree presented to a virtual machine. | 60 | as in the device tree presented to a virtual machine. |
| 51 | 61 | ||
| 52 | - msi-parent | ||
| 53 | Value type: <phandle> | ||
| 54 | Definition: Must be present and point to the MSI controller node | ||
| 55 | handling message interrupts for the MC. | ||
| 56 | |||
| 57 | - ranges | 62 | - ranges |
| 58 | Value type: <prop-encoded-array> | 63 | Value type: <prop-encoded-array> |
| 59 | Definition: A standard property. Defines the mapping between the child | 64 | Definition: A standard property. Defines the mapping between the child |
| @@ -119,6 +124,28 @@ Optional properties: · 59 unmodified lines | |||
| 119 | associated with the listed IOMMU, with the iommu-specifier | 124 | associated with the listed IOMMU, with the iommu-specifier |
| 120 | (i - icid-base + iommu-base). | 125 | (i - icid-base + iommu-base). |
| 121 | 126 | ||
| 127 | - msi-map: Maps an ICID to a GIC ITS and associated msi-specifier | ||
| 128 | data. | ||
| 129 | |||
| 130 | The property is an arbitrary number of tuples of | ||
| 131 | (icid-base,gic-its,msi-base,length). | ||
| 132 | |||
| 133 | Any ICID in the interval [icid-base, icid-base + length) is | ||
| 134 | associated with the listed GIC ITS, with the msi-specifier | ||
| 135 | (i - icid-base + msi-base). | ||
| 136 | |||
| 137 | Deprecated properties: | ||
| 138 | |||
| 139 | - msi-parent | ||
| 140 | Value type: <phandle> | ||
| 141 | Definition: Describes the MSI controller node handling message | ||
| 142 | interrupts for the MC. When there is no translation | ||
| 143 | between the ICID and deviceID this property can be used | ||
| 144 | to describe the MSI controller used by the devices on the | ||
| 145 | mc-bus. | ||
| 146 | The use of this property for mc-bus is deprecated. Please | ||
| 147 | use msi-map. | ||
| 148 | |||
| 122 | Example: | 149 | Example: |
| 123 | 150 | ||
| 124 | smmu: iommu@5000000 { | 151 | smmu: iommu@5000000 { |
| @@ -128,13 +155,24 @@ Example: · 3 unmodified lines | |||
| 128 | ... | 155 | ... |
| 129 | }; | 156 | }; |
| 130 | 157 | ||
| 158 | gic: interrupt-controller@6000000 { | ||
| 159 | compatible = "arm,gic-v3"; | ||
| 160 | ... | ||
| 161 | } | ||
| 162 | its: gic-its@6020000 { | ||
| 163 | compatible = "arm,gic-v3-its"; | ||
| 164 | msi-controller; | ||
| 165 | ... | ||
| 166 | }; | ||
| 167 | |||
| 131 | fsl_mc: fsl-mc@80c000000 { | 168 | fsl_mc: fsl-mc@80c000000 { |
| 132 | compatible = "fsl,qoriq-mc"; | 169 | compatible = "fsl,qoriq-mc"; |
| 133 | reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */ | 170 | reg = <0x00000008 0x0c000000 0 0x40>, /* MC portal base */ |
| 134 | <0x00000000 0x08340000 0 0x40000>; /* MC control reg */ | 171 | <0x00000000 0x08340000 0 0x40000>; /* MC control reg */ |
| 135 | msi-parent = <&its>; | ||
| 136 | /* define map for ICIDs 23-64 */ | 172 | /* define map for ICIDs 23-64 */ |
| 137 | iommu-map = <23 &smmu 23 41>; | 173 | iommu-map = <23 &smmu 23 41>; |
| 174 | /* define msi map for ICIDs 23-64 */ | ||
| 175 | msi-map = <23 &its 23 41>; | ||
| 138 | #address-cells = <3>; | 176 | #address-cells = <3>; |
| 139 | #size-cells = <1>; | 177 | #size-cells = <1>; |
| 140 | 178 | ||
| @@ -553,12 +553,12 @@ There are certain things that the Linux kernel memory barriers do not guarantee: · 552 unmodified lines | |||
| 553 | DATA DEPENDENCY BARRIERS (HISTORICAL) | 553 | DATA DEPENDENCY BARRIERS (HISTORICAL) |
| 554 | ------------------------------------- | 554 | ------------------------------------- |
| 555 | 555 | ||
| 556 | As of v4.15 of the Linux kernel, an smp_read_barrier_depends() was | 556 | As of v4.15 of the Linux kernel, an smp_mb() was added to READ_ONCE() for |
| 557 | added to READ_ONCE(), which means that about the only people who | 557 | DEC Alpha, which means that about the only people who need to pay attention |
| 558 | need to pay attention to this section are those working on DEC Alpha | 558 | to this section are those working on DEC Alpha architecture-specific code |
| 559 | architecture-specific code and those working on READ_ONCE() itself. | 559 | and those working on READ_ONCE() itself. For those who need it, and for |
| 560 | For those who need it, and for those who are interested in the history, | 560 | those who are interested in the history, here is the story of |
| 561 | here is the story of data-dependency barriers. | 561 | data-dependency barriers. |
| 562 | 562 | ||
| 563 | The usage requirements of data dependency barriers are a little subtle, and | 563 | The usage requirements of data dependency barriers are a little subtle, and |
| 564 | it's not always obvious that they're needed. To illustrate, consider the | 564 | it's not always obvious that they're needed. To illustrate, consider the |
| @@ -2708,144 +2708,6 @@ the properties of the memory window through which devices are accessed and/or · 2143 unmodified lines | |||
| 2708 | the use of any special device communication instructions the CPU may have. | 2708 | the use of any special device communication instructions the CPU may have. |
| 2709 | 2709 | ||
| 2710 | 2710 | ||
| 2711 | CACHE COHERENCY | ||
| 2712 | --------------- | ||
| 2713 | |||
| 2714 | Life isn't quite as simple as it may appear above, however: for while the | ||
| 2715 | caches are expected to be coherent, there's no guarantee that that coherency | ||
| 2716 | will be ordered. This means that while changes made on one CPU will | ||
| 2717 | eventually become visible on all CPUs, there's no guarantee that they will | ||
| 2718 | become apparent in the same order on those other CPUs. | ||
| 2719 | |||
| 2720 | |||
| 2721 | Consider dealing with a system that has a pair of CPUs (1 & 2), each of which | ||
| 2722 | has a pair of parallel data caches (CPU 1 has A/B, and CPU 2 has C/D): | ||
| 2723 | |||
| 2724 | : | ||
| 2725 | : +--------+ | ||
| 2726 | : +---------+ | | | ||
| 2727 | +--------+ : +--->| Cache A |<------->| | | ||
| 2728 | | | : | +---------+ | | | ||
| 2729 | | CPU 1 |<---+ | | | ||
| 2730 | | | : | +---------+ | | | ||
| 2731 | +--------+ : +--->| Cache B |<------->| | | ||
| 2732 | : +---------+ | | | ||
| 2733 | : | Memory | | ||
| 2734 | : +---------+ | System | | ||
| 2735 | +--------+ : +--->| Cache C |<------->| | | ||
| 2736 | | | : | +---------+ | | | ||
| 2737 | | CPU 2 |<---+ | | | ||
| 2738 | | | : | +---------+ | | | ||
| 2739 | +--------+ : +--->| Cache D |<------->| | | ||
| 2740 | : +---------+ | | | ||
| 2741 | : +--------+ | ||
| 2742 | : | ||
| 2743 | |||
| 2744 | Imagine the system has the following properties: | ||
| 2745 | |||
| 2746 | (*) an odd-numbered cache line may be in cache A, cache C or it may still be | ||
| 2747 | resident in memory; | ||
| 2748 | |||
| 2749 | (*) an even-numbered cache line may be in cache B, cache D or it may still be | ||
| 2750 | resident in memory; | ||
| 2751 | |||
| 2752 | (*) while the CPU core is interrogating one cache, the other cache may be | ||
| 2753 | making use of the bus to access the rest of the system - perhaps to | ||
| 2754 | displace a dirty cacheline or to do a speculative load; | ||
| 2755 | |||
| 2756 | (*) each cache has a queue of operations that need to be applied to that cache | ||
| 2757 | to maintain coherency with the rest of the system; | ||
| 2758 | |||
| 2759 | (*) the coherency queue is not flushed by normal loads to lines already | ||
| 2760 | present in the cache, even though the contents of the queue may | ||
| 2761 | potentially affect those loads. | ||
| 2762 | |||
| 2763 | Imagine, then, that two writes are made on the first CPU, with a write barrier | ||
| 2764 | between them to guarantee that they will appear to reach that CPU's caches in | ||
| 2765 | the requisite order: | ||
| 2766 | |||
| 2767 | CPU 1 CPU 2 COMMENT | ||
| 2768 | =============== =============== ======================================= | ||
| 2769 | u == 0, v == 1 and p == &u, q == &u | ||
| 2770 | v = 2; | ||
| 2771 | smp_wmb(); Make sure change to v is visible before | ||
| 2772 | change to p | ||
| 2773 | <A:modify v=2> v is now in cache A exclusively | ||
| 2774 | p = &v; | ||
| 2775 | <B:modify p=&v> p is now in cache B exclusively | ||
| 2776 | |||
| 2777 | The write memory barrier forces the other CPUs in the system to perceive that | ||
| 2778 | the local CPU's caches have apparently been updated in the correct order. But | ||
| 2779 | now imagine that the second CPU wants to read those values: | ||
| 2780 | |||
| 2781 | CPU 1 CPU 2 COMMENT | ||
| 2782 | =============== =============== ======================================= | ||
| 2783 | ... | ||
| 2784 | q = p; | ||
| 2785 | x = *q; | ||
| 2786 | |||
| 2787 | The above pair of reads may then fail to happen in the expected order, as the | ||
| 2788 | cacheline holding p may get updated in one of the second CPU's caches while | ||
| 2789 | the update to the cacheline holding v is delayed in the other of the second | ||
| 2790 | CPU's caches by some other cache event: | ||
| 2791 | |||
| 2792 | CPU 1 CPU 2 COMMENT | ||
| 2793 | =============== =============== ======================================= | ||
| 2794 | u == 0, v == 1 and p == &u, q == &u | ||
| 2795 | v = 2; | ||
| 2796 | smp_wmb(); | ||
| 2797 | <A:modify v=2> <C:busy> | ||
| 2798 | <C:queue v=2> | ||
| 2799 | p = &v; q = p; | ||
| 2800 | <D:request p> | ||
| 2801 | <B:modify p=&v> <D:commit p=&v> | ||
| 2802 | <D:read p> | ||
| 2803 | x = *q; | ||
| 2804 | <C:read *q> Reads from v before v updated in cache | ||
| 2805 | <C:unbusy> | ||
| 2806 | <C:commit v=2> | ||
| 2807 | |||
| 2808 | Basically, while both cachelines will be updated on CPU 2 eventually, there's | ||
| 2809 | no guarantee that, without intervention, the order of update will be the same | ||
| 2810 | as that committed on CPU 1. | ||
| 2811 | |||
| 2812 | |||
| 2813 | To intervene, we need to interpolate a data dependency barrier or a read | ||
| 2814 | barrier between the loads (which as of v4.15 is supplied unconditionally | ||
| 2815 | by the READ_ONCE() macro). This will force the cache to commit its | ||
| 2816 | coherency queue before processing any further requests: | ||
| 2817 | |||
| 2818 | CPU 1 CPU 2 COMMENT | ||
| 2819 | =============== =============== ======================================= | ||
| 2820 | u == 0, v == 1 and p == &u, q == &u | ||
| 2821 | v = 2; | ||
| 2822 | smp_wmb(); | ||
| 2823 | <A:modify v=2> <C:busy> | ||
| 2824 | <C:queue v=2> | ||
| 2825 | p = &v; q = p; | ||
| 2826 | <D:request p> | ||
| 2827 | <B:modify p=&v> <D:commit p=&v> | ||
| 2828 | <D:read p> | ||
| 2829 | smp_read_barrier_depends() | ||
| 2830 | <C:unbusy> | ||
| 2831 | <C:commit v=2> | ||
| 2832 | x = *q; | ||
| 2833 | <C:read *q> Reads from v after v updated in cache | ||
| 2834 | |||
| 2835 | |||
| 2836 | This sort of problem can be encountered on DEC Alpha processors as they have a | ||
| 2837 | split cache that improves performance by making better use of the data bus. | ||
| 2838 | While most CPUs do imply a data dependency barrier on the read when a memory | ||
| 2839 | access depends on a read, not all do, so it may not be relied on. | ||
| 2840 | |||
| 2841 | Other CPUs may also have split caches, but must coordinate between the various | ||
| 2842 | cachelets for normal memory accesses. The semantics of the Alpha removes the | ||
| 2843 | need for hardware coordination in the absence of memory barriers, which | ||
| 2844 | permitted Alpha to sport higher CPU clock rates back in the day. However, | ||
| 2845 | please note that (again, as of v4.15) smp_read_barrier_depends() should not | ||
| 2846 | be used except in Alpha arch-specific code and within the READ_ONCE() macro. | ||
| 2847 | |||
| 2848 | |||
| 2849 | CACHE COHERENCY VS DMA | 2711 | CACHE COHERENCY VS DMA |
| 2850 | ---------------------- | 2712 | ---------------------- |
| 2851 | 2713 | ||
| @@ -3009,10 +2871,8 @@ caches with the memory coherence system, thus making it seem like pointer · 157 unmodified lines | |||
| 3009 | changes vs new data occur in the right order. | 2871 | changes vs new data occur in the right order. |
| 3010 | 2872 | ||
| 3011 | The Alpha defines the Linux kernel's memory model, although as of v4.15 | 2873 | The Alpha defines the Linux kernel's memory model, although as of v4.15 |
| 3012 | the Linux kernel's addition of smp_read_barrier_depends() to READ_ONCE() | 2874 | the Linux kernel's addition of smp_mb() to READ_ONCE() on Alpha greatly |
| 3013 | greatly reduced Alpha's impact on the memory model. | 2875 | reduced its impact on the memory model. |
| 3014 | |||
| 3015 | See the subsection on "Cache Coherency" above. | ||
| 3016 | 2876 | ||
| 3017 | 2877 | ||
| 3018 | VIRTUAL MACHINE GUESTS | 2878 | VIRTUAL MACHINE GUESTS |
| @@ -577,7 +577,7 @@ ACQUIRE 는 해당 오퍼레이션의 로드 부분에만 적용되고 RELEASE · 576 unmodified lines | |||
| 577 | 데이터 의존성 배리어 (역사적) | 577 | 데이터 의존성 배리어 (역사적) |
| 578 | ----------------------------- | 578 | ----------------------------- |
| 579 | 579 | ||
| 580 | 리눅스 커널 v4.15 기준으로, smp_read_barrier_depends() 가 READ_ONCE() 에 | 580 | 리눅스 커널 v4.15 기준으로, smp_mb() 가 DEC Alpha 용 READ_ONCE() 코드에 |
| 581 | 추가되었는데, 이는 이 섹션에 주의를 기울여야 하는 사람들은 DEC Alpha 아키텍쳐 | 581 | 추가되었는데, 이는 이 섹션에 주의를 기울여야 하는 사람들은 DEC Alpha 아키텍쳐 |
| 582 | 전용 코드를 만드는 사람들과 READ_ONCE() 자체를 만드는 사람들 뿐임을 의미합니다. | 582 | 전용 코드를 만드는 사람들과 READ_ONCE() 자체를 만드는 사람들 뿐임을 의미합니다. |
| 583 | 그런 분들을 위해, 그리고 역사에 관심 있는 분들을 위해, 여기 데이터 의존성 | 583 | 그런 분들을 위해, 그리고 역사에 관심 있는 분들을 위해, 여기 데이터 의존성 |
| @@ -2664,144 +2664,6 @@ CPU 코어는 프로그램의 인과성이 유지된다고만 여겨진다면 · 2080 unmodified lines | |||
| 2664 | 수도 있습니다. | 2664 | 수도 있습니다. |
| 2665 | 2665 | ||
| 2666 | 2666 | ||
| 2667 | 캐시 일관성 | ||
| 2668 | ----------- | ||
| 2669 | |||
| 2670 | 하지만 삶은 앞에서 이야기한 것처럼 단순하지 않습니다: 캐시들은 일관적일 것으로 | ||
| 2671 | 기대되지만, 그 일관성이 순서에도 적용될 거라는 보장은 없습니다. 한 CPU 에서 | ||
| 2672 | 만들어진 변경 사항은 최종적으로는 시스템의 모든 CPU 에게 보여지게 되지만, 다른 | ||
| 2673 | CPU 들에게도 같은 순서로 보이게 될 거라는 보장은 없다는 뜻입니다. | ||
| 2674 | |||
| 2675 | |||
| 2676 | 두개의 CPU (1 & 2) 가 달려 있고, 각 CPU 에 두개의 데이터 캐시(CPU 1 은 A/B 를, | ||
| 2677 | CPU 2 는 C/D 를 갖습니다)가 병렬로 연결되어 있는 시스템을 다룬다고 생각해 | ||
| 2678 | 봅시다: | ||
| 2679 | |||
| 2680 | : | ||
| 2681 | : +--------+ | ||
| 2682 | : +---------+ | | | ||
| 2683 | +--------+ : +--->| Cache A |<------->| | | ||
| 2684 | | | : | +---------+ | | | ||
| 2685 | | CPU 1 |<---+ | | | ||
| 2686 | | | : | +---------+ | | | ||
| 2687 | +--------+ : +--->| Cache B |<------->| | | ||
| 2688 | : +---------+ | | | ||
| 2689 | : | Memory | | ||
| 2690 | : +---------+ | System | | ||
| 2691 | +--------+ : +--->| Cache C |<------->| | | ||
| 2692 | | | : | +---------+ | | | ||
| 2693 | | CPU 2 |<---+ | | | ||
| 2694 | | | : | +---------+ | | | ||
| 2695 | +--------+ : +--->| Cache D |<------->| | | ||
| 2696 | : +---------+ | | | ||
| 2697 | : +--------+ | ||
| 2698 | : | ||
| 2699 | |||
| 2700 | 이 시스템이 다음과 같은 특성을 갖는다 생각해 봅시다: | ||
| 2701 | |||
| 2702 | (*) 홀수번 캐시라인은 캐시 A, 캐시 C 또는 메모리에 위치할 수 있음; | ||
| 2703 | |||
| 2704 | (*) 짝수번 캐시라인은 캐시 B, 캐시 D 또는 메모리에 위치할 수 있음; | ||
| 2705 | |||
| 2706 | (*) CPU 코어가 한개의 캐시에 접근하는 동안, 다른 캐시는 - 더티 캐시라인을 | ||
| 2707 | 메모리에 내리거나 추측성 로드를 하거나 하기 위해 - 시스템의 다른 부분에 | ||
| 2708 | 액세스 하기 위해 버스를 사용할 수 있음; | ||
| 2709 | |||
| 2710 | (*) 각 캐시는 시스템의 나머지 부분들과 일관성을 맞추기 위해 해당 캐시에 | ||
| 2711 | 적용되어야 할 오퍼레이션들의 큐를 가짐; | ||
| 2712 | |||
| 2713 | (*) 이 일관성 큐는 캐시에 이미 존재하는 라인에 가해지는 평범한 로드에 의해서는 | ||
| 2714 | 비워지지 않는데, 큐의 오퍼레이션들이 이 로드의 결과에 영향을 끼칠 수 있다 | ||
| 2715 | 할지라도 그러함. | ||
| 2716 | |||
| 2717 | 이제, 첫번째 CPU 에서 두개의 쓰기 오퍼레이션을 만드는데, 해당 CPU 의 캐시에 | ||
| 2718 | 요청된 순서로 오퍼레이션이 도달됨을 보장하기 위해 두 오퍼레이션 사이에 쓰기 | ||
| 2719 | 배리어를 사용하는 상황을 상상해 봅시다: | ||
| 2720 | |||
| 2721 | CPU 1 CPU 2 COMMENT | ||
| 2722 | =============== =============== ======================================= | ||
| 2723 | u == 0, v == 1 and p == &u, q == &u | ||
| 2724 | v = 2; | ||
| 2725 | smp_wmb(); v 의 변경이 p 의 변경 전에 보일 것을 | ||
| 2726 | 분명히 함 | ||
| 2727 | <A:modify v=2> v 는 이제 캐시 A 에 독점적으로 존재함 | ||
| 2728 | p = &v; | ||
| 2729 | <B:modify p=&v> p 는 이제 캐시 B 에 독점적으로 존재함 | ||
| 2730 | |||
| 2731 | 여기서의 쓰기 메모리 배리어는 CPU 1 의 캐시가 올바른 순서로 업데이트 된 것으로 | ||
| 2732 | 시스템의 다른 CPU 들이 인지하게 만듭니다. 하지만, 이제 두번째 CPU 가 그 값들을 | ||
| 2733 | 읽으려 하는 상황을 생각해 봅시다: | ||
| 2734 | |||
| 2735 | CPU 1 CPU 2 COMMENT | ||
| 2736 | =============== =============== ======================================= | ||
| 2737 | ... | ||
| 2738 | q = p; | ||
| 2739 | x = *q; | ||
| 2740 | |||
| 2741 | 위의 두개의 읽기 오퍼레이션은 예상된 순서로 일어나지 못할 수 있는데, 두번째 CPU | ||
| 2742 | 의 한 캐시에 다른 캐시 이벤트가 발생해 v 를 담고 있는 캐시라인의 해당 캐시에의 | ||
| 2743 | 업데이트가 지연되는 사이, p 를 담고 있는 캐시라인은 두번째 CPU 의 다른 캐시에 | ||
| 2744 | 업데이트 되어버렸을 수 있기 때문입니다. | ||
| 2745 | |||
| 2746 | CPU 1 CPU 2 COMMENT | ||
| 2747 | =============== =============== ======================================= | ||
| 2748 | u == 0, v == 1 and p == &u, q == &u | ||
| 2749 | v = 2; | ||
| 2750 | smp_wmb(); | ||
| 2751 | <A:modify v=2> <C:busy> | ||
| 2752 | <C:queue v=2> | ||
| 2753 | p = &v; q = p; | ||
| 2754 | <D:request p> | ||
| 2755 | <B:modify p=&v> <D:commit p=&v> | ||
| 2756 | <D:read p> | ||
| 2757 | x = *q; | ||
| 2758 | <C:read *q> 캐시에 업데이트 되기 전의 v 를 읽음 | ||
| 2759 | <C:unbusy> | ||
| 2760 | <C:commit v=2> | ||
| 2761 | |||
| 2762 | 기본적으로, 두개의 캐시라인 모두 CPU 2 에 최종적으로는 업데이트 될 것이지만, | ||
| 2763 | 별도의 개입 없이는, 업데이트의 순서가 CPU 1 에서 만들어진 순서와 동일할 | ||
| 2764 | 것이라는 보장이 없습니다. | ||
| 2765 | |||
| 2766 | |||
| 2767 | 여기에 개입하기 위해선, 데이터 의존성 배리어나 읽기 배리어를 로드 오퍼레이션들 | ||
| 2768 | 사이에 넣어야 합니다 (v4.15 부터는 READ_ONCE() 매크로에 의해 무조건적으로 | ||
| 2769 | 그렇게 됩니다). 이렇게 함으로써 캐시가 다음 요청을 처리하기 전에 일관성 큐를 | ||
| 2770 | 처리하도록 강제하게 됩니다. | ||
| 2771 | |||
| 2772 | CPU 1 CPU 2 COMMENT | ||
| 2773 | =============== =============== ======================================= | ||
| 2774 | u == 0, v == 1 and p == &u, q == &u | ||
| 2775 | v = 2; | ||
| 2776 | smp_wmb(); | ||
| 2777 | <A:modify v=2> <C:busy> | ||
| 2778 | <C:queue v=2> | ||
| 2779 | p = &v; q = p; | ||
| 2780 | <D:request p> | ||
| 2781 | <B:modify p=&v> <D:commit p=&v> | ||
| 2782 | <D:read p> | ||
| 2783 | smp_read_barrier_depends() | ||
| 2784 | <C:unbusy> | ||
| 2785 | <C:commit v=2> | ||
| 2786 | x = *q; | ||
| 2787 | <C:read *q> 캐시에 업데이트 된 v 를 읽음 | ||
| 2788 | |||
| 2789 | |||
| 2790 | 이런 부류의 문제는 DEC Alpha 계열 프로세서들에서 발견될 수 있는데, 이들은 | ||
| 2791 | 데이터 버스를 좀 더 잘 사용해 성능을 개선할 수 있는, 분할된 캐시를 가지고 있기 | ||
| 2792 | 때문입니다. 대부분의 CPU 는 하나의 읽기 오퍼레이션의 메모리 액세스가 다른 읽기 | ||
| 2793 | 오퍼레이션에 의존적이라면 데이터 의존성 배리어를 내포시킵니다만, 모두가 그런건 | ||
| 2794 | 아니기 때문에 이점에 의존해선 안됩니다. | ||
| 2795 | |||
| 2796 | 다른 CPU 들도 분할된 캐시를 가지고 있을 수 있지만, 그런 CPU 들은 평범한 메모리 | ||
| 2797 | 액세스를 위해서도 이 분할된 캐시들 사이의 조정을 해야만 합니다. Alpha 는 가장 | ||
| 2798 | 약한 메모리 순서 시맨틱 (semantic) 을 선택함으로써 메모리 배리어가 명시적으로 | ||
| 2799 | 사용되지 않았을 때에는 그런 조정이 필요하지 않게 했으며, 이는 Alpha 가 당시에 | ||
| 2800 | 더 높은 CPU 클락 속도를 가질 수 있게 했습니다. 하지만, (다시 말하건대, v4.15 | ||
| 2801 | 이후부터는) Alpha 아키텍쳐 전용 코드와 READ_ONCE() 매크로 내부에서를 제외하고는 | ||
| 2802 | smp_read_barrier_depends() 가 사용되지 않아야 함을 알아두시기 바랍니다. | ||
| 2803 | |||
| 2804 | |||
| 2805 | 캐시 일관성 VS DMA | 2667 | 캐시 일관성 VS DMA |
| 2806 | ------------------ | 2668 | ------------------ |
| 2807 | 2669 | ||
| @@ -2962,10 +2824,8 @@ Alpha CPU 의 일부 버전은 분할된 데이터 캐시를 가지고 있어서 · 154 unmodified lines | |||
| 2962 | 데이터의 발견을 올바른 순서로 일어나게 하기 때문입니다. | 2824 | 데이터의 발견을 올바른 순서로 일어나게 하기 때문입니다. |
| 2963 | 2825 | ||
| 2964 | 리눅스 커널의 메모리 배리어 모델은 Alpha 에 기초해서 정의되었습니다만, v4.15 | 2826 | 리눅스 커널의 메모리 배리어 모델은 Alpha 에 기초해서 정의되었습니다만, v4.15 |
| 2965 | 부터는 리눅스 커널이 READ_ONCE() 내에 smp_read_barrier_depends() 를 추가해서 | 2827 | 부터는 Alpha 용 READ_ONCE() 코드 내에 smp_mb() 가 추가되어서 메모리 모델로의 |
| 2966 | Alpha 의 메모리 모델로의 영향력이 크게 줄어들긴 했습니다. | 2828 | Alpha 의 영향력이 크게 줄어들었습니다. |
| 2967 | |||
| 2968 | 위의 "캐시 일관성" 서브섹션을 참고하세요. | ||
| 2969 | 2829 | ||
| 2970 | 2830 | ||
| 2971 | 가상 머신 게스트 | 2831 | 가상 머신 게스트 |
| @@ -16,10 +16,10 @@ · 15 unmodified lines | |||
| 16 | 16 | ||
| 17 | /* | 17 | /* |
| 18 | * To ensure dependency ordering is preserved for the _relaxed and | 18 | * To ensure dependency ordering is preserved for the _relaxed and |
| 19 | * _release atomics, an smp_read_barrier_depends() is unconditionally | 19 | * _release atomics, an smp_mb() is unconditionally inserted into the |
| 20 | * inserted into the _relaxed variants, which are used to build the | 20 | * _relaxed variants, which are used to build the barriered versions. |
| 21 | * barriered versions. Avoid redundant back-to-back fences in the | 21 | * Avoid redundant back-to-back fences in the _acquire and _fence |
| 22 | * _acquire and _fence versions. | 22 | * versions. |
| 23 | */ | 23 | */ |
| 24 | #define __atomic_acquire_fence() | 24 | #define __atomic_acquire_fence() |
| 25 | #define __atomic_post_full_fence() | 25 | #define __atomic_post_full_fence() |
| @@ -70,7 +70,7 @@ static inline int atomic_##op##_return_relaxed(int i, atomic_t *v) \ · 44 unmodified lines | |||
| 70 | ".previous" \ | 70 | ".previous" \ |
| 71 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ | 71 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ |
| 72 | :"Ir" (i), "m" (v->counter) : "memory"); \ | 72 | :"Ir" (i), "m" (v->counter) : "memory"); \ |
| 73 | smp_read_barrier_depends(); \ | 73 | smp_mb(); \ |
| 74 | return result; \ | 74 | return result; \ |
| 75 | } | 75 | } |
| 76 | 76 | ||
| @@ -88,7 +88,7 @@ static inline int atomic_fetch_##op##_relaxed(int i, atomic_t *v) \ · 11 unmodified lines | |||
| 88 | ".previous" \ | 88 | ".previous" \ |
| 89 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ | 89 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ |
| 90 | :"Ir" (i), "m" (v->counter) : "memory"); \ | 90 | :"Ir" (i), "m" (v->counter) : "memory"); \ |
| 91 | smp_read_barrier_depends(); \ | 91 | smp_mb(); \ |
| 92 | return result; \ | 92 | return result; \ |
| 93 | } | 93 | } |
| 94 | 94 | ||
| @@ -123,7 +123,7 @@ static __inline__ s64 atomic64_##op##_return_relaxed(s64 i, atomic64_t * v) \ · 28 unmodified lines | |||
| 123 | ".previous" \ | 123 | ".previous" \ |
| 124 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ | 124 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ |
| 125 | :"Ir" (i), "m" (v->counter) : "memory"); \ | 125 | :"Ir" (i), "m" (v->counter) : "memory"); \ |
| 126 | smp_read_barrier_depends(); \ | 126 | smp_mb(); \ |
| 127 | return result; \ | 127 | return result; \ |
| 128 | } | 128 | } |
| 129 | 129 | ||
| @@ -141,7 +141,7 @@ static __inline__ s64 atomic64_fetch_##op##_relaxed(s64 i, atomic64_t * v) \ · 11 unmodified lines | |||
| 141 | ".previous" \ | 141 | ".previous" \ |
| 142 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ | 142 | :"=&r" (temp), "=m" (v->counter), "=&r" (result) \ |
| 143 | :"Ir" (i), "m" (v->counter) : "memory"); \ | 143 | :"Ir" (i), "m" (v->counter) : "memory"); \ |
| 144 | smp_read_barrier_depends(); \ | 144 | smp_mb(); \ |
| 145 | return result; \ | 145 | return result; \ |
| 146 | } | 146 | } |
| 147 | 147 | ||
| @@ -2,64 +2,15 @@ · 1 unmodified line | |||
| 2 | #ifndef __BARRIER_H | 2 | #ifndef __BARRIER_H |
| 3 | #define __BARRIER_H | 3 | #define __BARRIER_H |
| 4 | 4 | ||
| 5 | #include <asm/compiler.h> | ||
| 6 | |||
| 7 | #define mb() __asm__ __volatile__("mb": : :"memory") | 5 | #define mb() __asm__ __volatile__("mb": : :"memory") |
| 8 | #define rmb() __asm__ __volatile__("mb": : :"memory") | 6 | #define rmb() __asm__ __volatile__("mb": : :"memory") |
| 9 | #define wmb() __asm__ __volatile__("wmb": : :"memory") | 7 | #define wmb() __asm__ __volatile__("wmb": : :"memory") |
| 10 | 8 | ||
| 11 | /** | 9 | #define __smp_load_acquire(p) \ |
| 12 | * read_barrier_depends - Flush all pending reads that subsequents reads | 10 | ({ \ |
| 13 | * depend on. | 11 | compiletime_assert_atomic_type(*p); \ |
| 14 | * | 12 | __READ_ONCE(*p); \ |
| 15 | * No data-dependent reads from memory-like regions are ever reordered | 13 | }) |
| 16 | * over this barrier. All reads preceding this primitive are guaranteed | ||
| 17 | * to access memory (but not necessarily other CPUs' caches) before any | ||
| 18 | * reads following this primitive that depend on the data return by | ||
| 19 | * any of the preceding reads. This primitive is much lighter weight than | ||
| 20 | * rmb() on most CPUs, and is never heavier weight than is | ||
| 21 | * rmb(). | ||
| 22 | * | ||
| 23 | * These ordering constraints are respected by both the local CPU | ||
| 24 | * and the compiler. | ||
| 25 | * | ||
| 26 | * Ordering is not guaranteed by anything other than these primitives, | ||
| 27 | * not even by data dependencies. See the documentation for | ||
| 28 | * memory_barrier() for examples and URLs to more information. | ||
| 29 | * | ||
| 30 | * For example, the following code would force ordering (the initial | ||
| 31 | * value of "a" is zero, "b" is one, and "p" is "&a"): | ||
| 32 | * | ||
| 33 | * <programlisting> | ||
| 34 | * CPU 0 CPU 1 | ||
| 35 | * | ||
| 36 | * b = 2; | ||
| 37 | * memory_barrier(); | ||
| 38 | * p = &b; q = p; | ||
| 39 | * read_barrier_depends(); | ||
| 40 | * d = *q; | ||
| 41 | * </programlisting> | ||
| 42 | * | ||
| 43 | * because the read of "*q" depends on the read of "p" and these | ||
| 44 | * two reads are separated by a read_barrier_depends(). However, | ||
| 45 | * the following code, with the same initial values for "a" and "b": | ||
| 46 | * | ||
| 47 | * <programlisting> | ||
| 48 | * CPU 0 CPU 1 | ||
| 49 | * | ||
| 50 | * a = 2; | ||
| 51 | * memory_barrier(); | ||
| 52 | * b = 3; y = b; | ||
| 53 | * read_barrier_depends(); | ||
| 54 | * x = a; | ||
| 55 | * </programlisting> | ||
| 56 | * | ||
| 57 | * does not enforce ordering, since there is no data dependency between | ||
| 58 | * the read of "a" and the read of "b". Therefore, on some CPUs, such | ||
| 59 | * as Alpha, "y" could be set to 3 and "x" to 0. Use rmb() | ||
| 60 | * in cases like this where there are no data dependencies. | ||
| 61 | */ | ||
| 62 | #define read_barrier_depends() __asm__ __volatile__("mb": : :"memory") | ||
| 63 | 14 | ||
| 64 | #ifdef CONFIG_SMP | 15 | #ifdef CONFIG_SMP |
| 65 | #define __ASM_SMP_MB "\tmb\n" | 16 | #define __ASM_SMP_MB "\tmb\n" |
| @@ -277,9 +277,9 @@ extern inline pte_t pte_mkdirty(pte_t pte) { pte_val(pte) |= __DIRTY_BITS; retur · 276 unmodified lines | |||
| 277 | extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } | 277 | extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; return pte; } |
| 278 | 278 | ||
| 279 | /* | 279 | /* |
| 280 | * The smp_read_barrier_depends() in the following functions are required to | 280 | * The smp_rmb() in the following functions are required to order the load of |
| 281 | * order the load of *dir (the pointer in the top level page table) with any | 281 | * *dir (the pointer in the top level page table) with any subsequent load of |
| 282 | * subsequent load of the returned pmd_t *ret (ret is data dependent on *dir). | 282 | * the returned pmd_t *ret (ret is data dependent on *dir). |
| 283 | * | 283 | * |
| 284 | * If this ordering is not enforced, the CPU might load an older value of | 284 | * If this ordering is not enforced, the CPU might load an older value of |
| 285 | * *ret, which may be uninitialized data. See mm/memory.c:__pte_alloc for | 285 | * *ret, which may be uninitialized data. See mm/memory.c:__pte_alloc for |
| @@ -293,7 +293,7 @@ extern inline pte_t pte_mkyoung(pte_t pte) { pte_val(pte) |= __ACCESS_BITS; retu · 7 unmodified lines | |||
| 293 | extern inline pmd_t * pmd_offset(pud_t * dir, unsigned long address) | 293 | extern inline pmd_t * pmd_offset(pud_t * dir, unsigned long address) |
| 294 | { | 294 | { |
| 295 | pmd_t *ret = (pmd_t *) pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); | 295 | pmd_t *ret = (pmd_t *) pud_page_vaddr(*dir) + ((address >> PMD_SHIFT) & (PTRS_PER_PAGE - 1)); |
| 296 | smp_read_barrier_depends(); /* see above */ | 296 | smp_rmb(); /* see above */ |
| 297 | return ret; | 297 | return ret; |
| 298 | } | 298 | } |
| 299 | #define pmd_offset pmd_offset | 299 | #define pmd_offset pmd_offset |
| @@ -303,7 +303,7 @@ extern inline pte_t * pte_offset_kernel(pmd_t * dir, unsigned long address) · 3 unmodified lines | |||
| 303 | { | 303 | { |
| 304 | pte_t *ret = (pte_t *) pmd_page_vaddr(*dir) | 304 | pte_t *ret = (pte_t *) pmd_page_vaddr(*dir) |
| 305 | + ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1)); | 305 | + ((address >> PAGE_SHIFT) & (PTRS_PER_PAGE - 1)); |
| 306 | smp_read_barrier_depends(); /* see above */ | 306 | smp_rmb(); /* see above */ |
| 307 | return ret; | 307 | return ret; |
| 308 | } | 308 | } |
| 309 | #define pte_offset_kernel pte_offset_kernel | 309 | #define pte_offset_kernel pte_offset_kernel |
| @@ -0,0 +1,35 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Copyright (C) 2019 Google LLC. | ||
| 4 | */ | ||
| 5 | #ifndef __ASM_RWONCE_H | ||
| 6 | #define __ASM_RWONCE_H | ||
| 7 | |||
| 8 | #ifdef CONFIG_SMP | ||
| 9 | |||
| 10 | #include <asm/barrier.h> | ||
| 11 | |||
| 12 | /* | ||
| 13 | * Alpha is apparently daft enough to reorder address-dependent loads | ||
| 14 | * on some CPU implementations. Knock some common sense into it with | ||
| 15 | * a memory barrier in READ_ONCE(). | ||
| 16 | * | ||
| 17 | * For the curious, more information about this unusual reordering is | ||
| 18 | * available in chapter 15 of the "perfbook": | ||
| 19 | * | ||
| 20 | * https://kernel.org/pub/linux/kernel/people/paulmck/perfbook/perfbook.html | ||
| 21 | * | ||
| 22 | */ | ||
| 23 | #define __READ_ONCE(x) \ | ||
| 24 | ({ \ | ||
| 25 | __unqual_scalar_typeof(x) __x = \ | ||
| 26 | (*(volatile typeof(__x) *)(&(x))); \ | ||
| 27 | mb(); \ | ||
| 28 | (typeof(x))__x; \ | ||
| 29 | }) | ||
| 30 | |||
| 31 | #endif /* CONFIG_SMP */ | ||
| 32 | |||
| 33 | #include <asm-generic/rwonce.h> | ||
| 34 | |||
| 35 | #endif /* __ASM_RWONCE_H */ | ||
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #ifndef __ASSEMBLY__ | 8 | #ifndef __ASSEMBLY__ |
| 9 | 9 | ||
| 10 | #include <asm/barrier.h> | ||
| 10 | #include <asm/errno.h> | 11 | #include <asm/errno.h> |
| 11 | #include <asm/unistd.h> | 12 | #include <asm/unistd.h> |
| 12 | #include <asm/vdso/cp15.h> | 13 | #include <asm/vdso/cp15.h> |
| @@ -118,6 +118,7 @@ config ARM64 · 117 unmodified lines | |||
| 118 | select GENERIC_STRNLEN_USER | 118 | select GENERIC_STRNLEN_USER |
| 119 | select GENERIC_TIME_VSYSCALL | 119 | select GENERIC_TIME_VSYSCALL |
| 120 | select GENERIC_GETTIMEOFDAY | 120 | select GENERIC_GETTIMEOFDAY |
| 121 | select GENERIC_VDSO_TIME_NS | ||
| 121 | select HANDLE_DOMAIN_IRQ | 122 | select HANDLE_DOMAIN_IRQ |
| 122 | select HARDIRQS_SW_RESEND | 123 | select HARDIRQS_SW_RESEND |
| 123 | select HAVE_PCI | 124 | select HAVE_PCI |
| @@ -1327,6 +1328,8 @@ config SWP_EMULATION · 1203 unmodified lines | |||
| 1327 | ARMv8 obsoletes the use of A32 SWP/SWPB instructions such that | 1328 | ARMv8 obsoletes the use of A32 SWP/SWPB instructions such that |
| 1328 | they are always undefined. Say Y here to enable software | 1329 | they are always undefined. Say Y here to enable software |
| 1329 | emulation of these instructions for userspace using LDXR/STXR. | 1330 | emulation of these instructions for userspace using LDXR/STXR. |
| 1331 | This feature can be controlled at runtime with the abi.swp | ||
| 1332 | sysctl which is disabled by default. | ||
| 1330 | 1333 | ||
| 1331 | In some older versions of glibc [<=2.8] SWP is used during futex | 1334 | In some older versions of glibc [<=2.8] SWP is used during futex |
| 1332 | trylock() operations with the assumption that the code will not | 1335 | trylock() operations with the assumption that the code will not |
| @@ -1353,7 +1356,8 @@ config CP15_BARRIER_EMULATION · 20 unmodified lines | |||
| 1353 | Say Y here to enable software emulation of these | 1356 | Say Y here to enable software emulation of these |
| 1354 | instructions for AArch32 userspace code. When this option is | 1357 | instructions for AArch32 userspace code. When this option is |
| 1355 | enabled, CP15 barrier usage is traced which can help | 1358 | enabled, CP15 barrier usage is traced which can help |
| 1356 | identify software that needs updating. | 1359 | identify software that needs updating. This feature can be |
| 1360 | controlled at runtime with the abi.cp15_barrier sysctl. | ||
| 1357 | 1361 | ||
| 1358 | If unsure, say Y | 1362 | If unsure, say Y |
| 1359 | 1363 | ||
| @@ -1364,7 +1368,8 @@ config SETEND_EMULATION · 4 unmodified lines | |||
| 1364 | AArch32 EL0, and is deprecated in ARMv8. | 1368 | AArch32 EL0, and is deprecated in ARMv8. |
| 1365 | 1369 | ||
| 1366 | Say Y here to enable software emulation of the instruction | 1370 | Say Y here to enable software emulation of the instruction |
| 1367 | for AArch32 userspace code. | 1371 | for AArch32 userspace code. This feature can be controlled |
| 1372 | at runtime with the abi.setend sysctl. | ||
| 1368 | 1373 | ||
| 1369 | Note: All the cpus on the system must have mixed endian support at EL0 | 1374 | Note: All the cpus on the system must have mixed endian support at EL0 |
| 1370 | for this feature to be enabled. If a new CPU - which doesn't support mixed | 1375 | for this feature to be enabled. If a new CPU - which doesn't support mixed |
| @@ -1596,6 +1601,20 @@ config ARM64_AMU_EXTN · 225 unmodified lines | |||
| 1596 | correctly reflect reality. Most commonly, the value read will be 0, | 1601 | correctly reflect reality. Most commonly, the value read will be 0, |
| 1597 | indicating that the counter is not enabled. | 1602 | indicating that the counter is not enabled. |
| 1598 | 1603 | ||
| 1604 | config AS_HAS_ARMV8_4 | ||
| 1605 | def_bool $(cc-option,-Wa$(comma)-march=armv8.4-a) | ||
| 1606 | |||
| 1607 | config ARM64_TLB_RANGE | ||
| 1608 | bool "Enable support for tlbi range feature" | ||
| 1609 | default y | ||
| 1610 | depends on AS_HAS_ARMV8_4 | ||
| 1611 | help | ||
| 1612 | ARMv8.4-TLBI provides TLBI invalidation instruction that apply to a | ||
| 1613 | range of input addresses. | ||
| 1614 | |||
| 1615 | The feature introduces new assembly instructions, and they were | ||
| 1616 | support when binutils >= 2.30. | ||
| 1617 | |||
| 1599 | endmenu | 1618 | endmenu |
| 1600 | 1619 | ||
| 1601 | menu "ARMv8.5 architectural features" | 1620 | menu "ARMv8.5 architectural features" |
| @@ -82,11 +82,18 @@ endif · 81 unmodified lines | |||
| 82 | # compiler to generate them and consequently to break the single image contract | 82 | # compiler to generate them and consequently to break the single image contract |
| 83 | # we pass it only to the assembler. This option is utilized only in case of non | 83 | # we pass it only to the assembler. This option is utilized only in case of non |
| 84 | # integrated assemblers. | 84 | # integrated assemblers. |
| 85 | ifneq ($(CONFIG_AS_HAS_ARMV8_4), y) | ||
| 85 | branch-prot-flags-$(CONFIG_AS_HAS_PAC) += -Wa,-march=armv8.3-a | 86 | branch-prot-flags-$(CONFIG_AS_HAS_PAC) += -Wa,-march=armv8.3-a |
| 86 | endif | 87 | endif |
| 88 | endif | ||
| 87 | 89 | ||
| 88 | KBUILD_CFLAGS += $(branch-prot-flags-y) | 90 | KBUILD_CFLAGS += $(branch-prot-flags-y) |
| 89 | 91 | ||
| 92 | ifeq ($(CONFIG_AS_HAS_ARMV8_4), y) | ||
| 93 | # make sure to pass the newest target architecture to -march. | ||
| 94 | KBUILD_CFLAGS += -Wa,-march=armv8.4-a | ||
| 95 | endif | ||
| 96 | |||
| 90 | ifeq ($(CONFIG_SHADOW_CALL_STACK), y) | 97 | ifeq ($(CONFIG_SHADOW_CALL_STACK), y) |
| 91 | KBUILD_CFLAGS += -ffixed-x18 | 98 | KBUILD_CFLAGS += -ffixed-x18 |
| 92 | endif | 99 | endif |
| @@ -66,6 +66,7 @@ CONFIG_SCHED_SMT=y · 65 unmodified lines | |||
| 66 | CONFIG_NUMA=y | 66 | CONFIG_NUMA=y |
| 67 | CONFIG_SECCOMP=y | 67 | CONFIG_SECCOMP=y |
| 68 | CONFIG_KEXEC=y | 68 | CONFIG_KEXEC=y |
| 69 | CONFIG_KEXEC_FILE=y | ||
| 69 | CONFIG_CRASH_DUMP=y | 70 | CONFIG_CRASH_DUMP=y |
| 70 | CONFIG_XEN=y | 71 | CONFIG_XEN=y |
| 71 | CONFIG_COMPAT=y | 72 | CONFIG_COMPAT=y |
| @@ -47,20 +47,7 @@ · 46 unmodified lines | |||
| 47 | pgprot_t __acpi_get_mem_attribute(phys_addr_t addr); | 47 | pgprot_t __acpi_get_mem_attribute(phys_addr_t addr); |
| 48 | 48 | ||
| 49 | /* ACPI table mapping after acpi_permanent_mmap is set */ | 49 | /* ACPI table mapping after acpi_permanent_mmap is set */ |
| 50 | static inline void __iomem *acpi_os_ioremap(acpi_physical_address phys, | 50 | void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size); |
| 51 | acpi_size size) | ||
| 52 | { | ||
| 53 | /* For normal memory we already have a cacheable mapping. */ | ||
| 54 | if (memblock_is_map_memory(phys)) | ||
| 55 | return (void __iomem *)__phys_to_virt(phys); | ||
| 56 | |||
| 57 | /* | ||
| 58 | * We should still honor the memory's attribute here because | ||
| 59 | * crash dump kernel possibly excludes some ACPI (reclaim) | ||
| 60 | * regions from memblock list. | ||
| 61 | */ | ||
| 62 | return __ioremap(phys, size, __acpi_get_mem_attribute(phys)); | ||
| 63 | } | ||
| 64 | #define acpi_os_ioremap acpi_os_ioremap | 51 | #define acpi_os_ioremap acpi_os_ioremap |
| 65 | 52 | ||
| 66 | typedef u64 phys_cpuid_t; | 53 | typedef u64 phys_cpuid_t; |
| @@ -62,7 +62,9 @@ · 61 unmodified lines | |||
| 62 | #define ARM64_HAS_GENERIC_AUTH 52 | 62 | #define ARM64_HAS_GENERIC_AUTH 52 |
| 63 | #define ARM64_HAS_32BIT_EL1 53 | 63 | #define ARM64_HAS_32BIT_EL1 53 |
| 64 | #define ARM64_BTI 54 | 64 | #define ARM64_BTI 54 |
| 65 | #define ARM64_HAS_ARMv8_4_TTL 55 | ||
| 66 | #define ARM64_HAS_TLB_RANGE 56 | ||
| 65 | 67 | ||
| 66 | #define ARM64_NCAPS 55 | 68 | #define ARM64_NCAPS 57 |
| 67 | 69 | ||
| 68 | #endif /* __ASM_CPUCAPS_H */ | 70 | #endif /* __ASM_CPUCAPS_H */ |
| @@ -692,6 +692,12 @@ static inline bool system_supports_bti(void) · 691 unmodified lines | |||
| 692 | return IS_ENABLED(CONFIG_ARM64_BTI) && cpus_have_const_cap(ARM64_BTI); | 692 | return IS_ENABLED(CONFIG_ARM64_BTI) && cpus_have_const_cap(ARM64_BTI); |
| 693 | } | 693 | } |
| 694 | 694 | ||
| 695 | static inline bool system_supports_tlb_range(void) | ||
| 696 | { | ||
| 697 | return IS_ENABLED(CONFIG_ARM64_TLB_RANGE) && | ||
| 698 | cpus_have_const_cap(ARM64_HAS_TLB_RANGE); | ||
| 699 | } | ||
| 700 | |||
| 695 | #define ARM64_BP_HARDEN_UNKNOWN -1 | 701 | #define ARM64_BP_HARDEN_UNKNOWN -1 |
| 696 | #define ARM64_BP_HARDEN_WA_NEEDED 0 | 702 | #define ARM64_BP_HARDEN_WA_NEEDED 0 |
| 697 | #define ARM64_BP_HARDEN_NOT_REQUIRED 1 | 703 | #define ARM64_BP_HARDEN_NOT_REQUIRED 1 |
| @@ -774,6 +780,7 @@ static inline unsigned int get_vmid_bits(u64 mmfr1) · 76 unmodified lines | |||
| 774 | } | 780 | } |
| 775 | 781 | ||
| 776 | u32 get_kvm_ipa_limit(void); | 782 | u32 get_kvm_ipa_limit(void); |
| 783 | void dump_cpu_features(void); | ||
| 777 | 784 | ||
| 778 | #endif /* __ASSEMBLY__ */ | 785 | #endif /* __ASSEMBLY__ */ |
| 779 | 786 | ||
| @@ -49,6 +49,8 @@ extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long addr, · 48 unmodified lines | |||
| 49 | pte_t *ptep, pte_t pte, unsigned long sz); | 49 | pte_t *ptep, pte_t pte, unsigned long sz); |
| 50 | #define set_huge_swap_pte_at set_huge_swap_pte_at | 50 | #define set_huge_swap_pte_at set_huge_swap_pte_at |
| 51 | 51 | ||
| 52 | void __init arm64_hugetlb_cma_reserve(void); | ||
| 53 | |||
| 52 | #include <asm-generic/hugetlb.h> | 54 | #include <asm-generic/hugetlb.h> |
| 53 | 55 | ||
| 54 | #endif /* __ASM_HUGETLB_H */ | 56 | #endif /* __ASM_HUGETLB_H */ |
| @@ -95,6 +95,7 @@ · 94 unmodified lines | |||
| 95 | #define KERNEL_HWCAP_DGH __khwcap2_feature(DGH) | 95 | #define KERNEL_HWCAP_DGH __khwcap2_feature(DGH) |
| 96 | #define KERNEL_HWCAP_RNG __khwcap2_feature(RNG) | 96 | #define KERNEL_HWCAP_RNG __khwcap2_feature(RNG) |
| 97 | #define KERNEL_HWCAP_BTI __khwcap2_feature(BTI) | 97 | #define KERNEL_HWCAP_BTI __khwcap2_feature(BTI) |
| 98 | /* reserved for KERNEL_HWCAP_MTE __khwcap2_feature(MTE) */ | ||
| 98 | 99 | ||
| 99 | /* | 100 | /* |
| 100 | * This yields a mask that user programs can use to figure out what | 101 | * This yields a mask that user programs can use to figure out what |
| @@ -8,7 +8,7 @@ · 7 unmodified lines | |||
| 8 | #ifndef __ASM_KERNEL_PGTABLE_H | 8 | #ifndef __ASM_KERNEL_PGTABLE_H |
| 9 | #define __ASM_KERNEL_PGTABLE_H | 9 | #define __ASM_KERNEL_PGTABLE_H |
| 10 | 10 | ||
| 11 | #include <linux/pgtable.h> | 11 | #include <asm/pgtable-hwdef.h> |
| 12 | #include <asm/sparsemem.h> | 12 | #include <asm/sparsemem.h> |
| 13 | 13 | ||
| 14 | /* | 14 | /* |
| @@ -10,11 +10,8 @@ · 9 unmodified lines | |||
| 10 | #ifndef __ASM_MEMORY_H | 10 | #ifndef __ASM_MEMORY_H |
| 11 | #define __ASM_MEMORY_H | 11 | #define __ASM_MEMORY_H |
| 12 | 12 | ||
| 13 | #include <linux/compiler.h> | ||
| 14 | #include <linux/const.h> | 13 | #include <linux/const.h> |
| 15 | #include <linux/sizes.h> | 14 | #include <linux/sizes.h> |
| 16 | #include <linux/types.h> | ||
| 17 | #include <asm/bug.h> | ||
| 18 | #include <asm/page-def.h> | 15 | #include <asm/page-def.h> |
| 19 | 16 | ||
| 20 | /* | 17 | /* |
| @@ -157,11 +154,15 @@ · 136 unmodified lines | |||
| 157 | #endif | 154 | #endif |
| 158 | 155 | ||
| 159 | #ifndef __ASSEMBLY__ | 156 | #ifndef __ASSEMBLY__ |
| 160 | extern u64 vabits_actual; | ||
| 161 | #define PAGE_END (_PAGE_END(vabits_actual)) | ||
| 162 | 157 | ||
| 163 | #include <linux/bitops.h> | 158 | #include <linux/bitops.h> |
| 159 | #include <linux/compiler.h> | ||
| 164 | #include <linux/mmdebug.h> | 160 | #include <linux/mmdebug.h> |
| 161 | #include <linux/types.h> | ||
| 162 | #include <asm/bug.h> | ||
| 163 | |||
| 164 | extern u64 vabits_actual; | ||
| 165 | #define PAGE_END (_PAGE_END(vabits_actual)) | ||
| 165 | 166 | ||
| 166 | extern s64 physvirt_offset; | 167 | extern s64 physvirt_offset; |
| 167 | extern s64 memstart_addr; | 168 | extern s64 memstart_addr; |
| @@ -322,6 +323,7 @@ static inline void *phys_to_virt(phys_addr_t x) · 154 unmodified lines | |||
| 322 | __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr)); \ | 323 | __is_lm_address(__addr) && pfn_valid(virt_to_pfn(__addr)); \ |
| 323 | }) | 324 | }) |
| 324 | 325 | ||
| 326 | void dump_mem_limit(void); | ||
| 325 | #endif /* !ASSEMBLY */ | 327 | #endif /* !ASSEMBLY */ |
| 326 | 328 | ||
| 327 | /* | 329 | /* |
| @@ -175,7 +175,7 @@ static inline void cpu_replace_ttbr1(pgd_t *pgdp) · 174 unmodified lines | |||
| 175 | * take CPU migration into account. | 175 | * take CPU migration into account. |
| 176 | */ | 176 | */ |
| 177 | #define destroy_context(mm) do { } while(0) | 177 | #define destroy_context(mm) do { } while(0) |
| 178 | void check_and_switch_context(struct mm_struct *mm, unsigned int cpu); | 178 | void check_and_switch_context(struct mm_struct *mm); |
| 179 | 179 | ||
| 180 | #define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; }) | 180 | #define init_new_context(tsk,mm) ({ atomic64_set(&(mm)->context.id, 0); 0; }) |
| 181 | 181 | ||
| @@ -214,8 +214,6 @@ enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk) · 32 unmodified lines | |||
| 214 | 214 | ||
| 215 | static inline void __switch_mm(struct mm_struct *next) | 215 | static inline void __switch_mm(struct mm_struct *next) |
| 216 | { | 216 | { |
| 217 | unsigned int cpu = smp_processor_id(); | ||
| 218 | |||
| 219 | /* | 217 | /* |
| 220 | * init_mm.pgd does not contain any user mappings and it is always | 218 | * init_mm.pgd does not contain any user mappings and it is always |
| 221 | * active for kernel addresses in TTBR1. Just set the reserved TTBR0. | 219 | * active for kernel addresses in TTBR1. Just set the reserved TTBR0. |
| @@ -225,7 +223,7 @@ static inline void __switch_mm(struct mm_struct *next) · 3 unmodified lines | |||
| 225 | return; | 223 | return; |
| 226 | } | 224 | } |
| 227 | 225 | ||
| 228 | check_and_switch_context(next, cpu); | 226 | check_and_switch_context(next); |
| 229 | } | 227 | } |
| 230 | 228 | ||
| 231 | static inline void | 229 | static inline void |
| @@ -72,6 +72,13 @@ · 71 unmodified lines | |||
| 72 | #define ARMV8_PMUV3_PERFCTR_LL_CACHE_RD 0x36 | 72 | #define ARMV8_PMUV3_PERFCTR_LL_CACHE_RD 0x36 |
| 73 | #define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD 0x37 | 73 | #define ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD 0x37 |
| 74 | #define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD 0x38 | 74 | #define ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD 0x38 |
| 75 | #define ARMV8_PMUV3_PERFCTR_L1D_CACHE_LMISS_RD 0x39 | ||
| 76 | #define ARMV8_PMUV3_PERFCTR_OP_RETIRED 0x3A | ||
| 77 | #define ARMV8_PMUV3_PERFCTR_OP_SPEC 0x3B | ||
| 78 | #define ARMV8_PMUV3_PERFCTR_STALL 0x3C | ||
| 79 | #define ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND 0x3D | ||
| 80 | #define ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND 0x3E | ||
| 81 | #define ARMV8_PMUV3_PERFCTR_STALL_SLOT 0x3F | ||
| 75 | 82 | ||
| 76 | /* Statistical profiling extension microarchitectural events */ | 83 | /* Statistical profiling extension microarchitectural events */ |
| 77 | #define ARMV8_SPE_PERFCTR_SAMPLE_POP 0x4000 | 84 | #define ARMV8_SPE_PERFCTR_SAMPLE_POP 0x4000 |
| @@ -79,6 +86,26 @@ · 1 unmodified line | |||
| 79 | #define ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE 0x4002 | 86 | #define ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE 0x4002 |
| 80 | #define ARMV8_SPE_PERFCTR_SAMPLE_COLLISION 0x4003 | 87 | #define ARMV8_SPE_PERFCTR_SAMPLE_COLLISION 0x4003 |
| 81 | 88 | ||
| 89 | /* AMUv1 architecture events */ | ||
| 90 | #define ARMV8_AMU_PERFCTR_CNT_CYCLES 0x4004 | ||
| 91 | #define ARMV8_AMU_PERFCTR_STALL_BACKEND_MEM 0x4005 | ||
| 92 | |||
| 93 | /* long-latency read miss events */ | ||
| 94 | #define ARMV8_PMUV3_PERFCTR_L1I_CACHE_LMISS 0x4006 | ||
| 95 | #define ARMV8_PMUV3_PERFCTR_L2D_CACHE_LMISS_RD 0x4009 | ||
| 96 | #define ARMV8_PMUV3_PERFCTR_L2I_CACHE_LMISS 0x400A | ||
| 97 | #define ARMV8_PMUV3_PERFCTR_L3D_CACHE_LMISS_RD 0x400B | ||
| 98 | |||
| 99 | /* additional latency from alignment events */ | ||
| 100 | #define ARMV8_PMUV3_PERFCTR_LDST_ALIGN_LAT 0x4020 | ||
| 101 | #define ARMV8_PMUV3_PERFCTR_LD_ALIGN_LAT 0x4021 | ||
| 102 | #define ARMV8_PMUV3_PERFCTR_ST_ALIGN_LAT 0x4022 | ||
| 103 | |||
| 104 | /* Armv8.5 Memory Tagging Extension events */ | ||
| 105 | #define ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED 0x4024 | ||
| 106 | #define ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED_RD 0x4025 | ||
| 107 | #define ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED_WR 0x4026 | ||
| 108 | |||
| 82 | /* ARMv8 recommended implementation defined event types */ | 109 | /* ARMv8 recommended implementation defined event types */ |
| 83 | #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD 0x40 | 110 | #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_RD 0x40 |
| 84 | #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR 0x41 | 111 | #define ARMV8_IMPDEF_PERFCTR_L1D_CACHE_WR 0x41 |
| @@ -29,7 +29,7 @@ · 28 unmodified lines | |||
| 29 | * Size mapped by an entry at level n ( 0 <= n <= 3) | 29 | * Size mapped by an entry at level n ( 0 <= n <= 3) |
| 30 | * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits | 30 | * We map (PAGE_SHIFT - 3) at all translation levels and PAGE_SHIFT bits |
| 31 | * in the final page. The maximum number of translation levels supported by | 31 | * in the final page. The maximum number of translation levels supported by |
| 32 | * the architecture is 4. Hence, starting at at level n, we have further | 32 | * the architecture is 4. Hence, starting at level n, we have further |
| 33 | * ((4 - n) - 1) levels of translation excluding the offset within the page. | 33 | * ((4 - n) - 1) levels of translation excluding the offset within the page. |
| 34 | * So, the total number of bits mapped by an entry at level n is : | 34 | * So, the total number of bits mapped by an entry at level n is : |
| 35 | * | 35 | * |
| @@ -82,23 +82,23 @@ · 46 unmodified lines | |||
| 82 | * Contiguous page definitions. | 82 | * Contiguous page definitions. |
| 83 | */ | 83 | */ |
| 84 | #ifdef CONFIG_ARM64_64K_PAGES | 84 | #ifdef CONFIG_ARM64_64K_PAGES |
| 85 | #define CONT_PTE_SHIFT 5 | 85 | #define CONT_PTE_SHIFT (5 + PAGE_SHIFT) |
| 86 | #define CONT_PMD_SHIFT 5 | 86 | #define CONT_PMD_SHIFT (5 + PMD_SHIFT) |
| 87 | #elif defined(CONFIG_ARM64_16K_PAGES) | 87 | #elif defined(CONFIG_ARM64_16K_PAGES) |
| 88 | #define CONT_PTE_SHIFT 7 | 88 | #define CONT_PTE_SHIFT (7 + PAGE_SHIFT) |
| 89 | #define CONT_PMD_SHIFT 5 | 89 | #define CONT_PMD_SHIFT (5 + PMD_SHIFT) |
| 90 | #else | 90 | #else |
| 91 | #define CONT_PTE_SHIFT 4 | 91 | #define CONT_PTE_SHIFT (4 + PAGE_SHIFT) |
| 92 | #define CONT_PMD_SHIFT 4 | 92 | #define CONT_PMD_SHIFT (4 + PMD_SHIFT) |
| 93 | #endif | 93 | #endif |
| 94 | 94 | ||
| 95 | #define CONT_PTES (1 << CONT_PTE_SHIFT) | 95 | #define CONT_PTES (1 << (CONT_PTE_SHIFT - PAGE_SHIFT)) |
| 96 | #define CONT_PTE_SIZE (CONT_PTES * PAGE_SIZE) | 96 | #define CONT_PTE_SIZE (CONT_PTES * PAGE_SIZE) |
| 97 | #define CONT_PTE_MASK (~(CONT_PTE_SIZE - 1)) | 97 | #define CONT_PTE_MASK (~(CONT_PTE_SIZE - 1)) |
| 98 | #define CONT_PMDS (1 << CONT_PMD_SHIFT) | 98 | #define CONT_PMDS (1 << (CONT_PMD_SHIFT - PMD_SHIFT)) |
| 99 | #define CONT_PMD_SIZE (CONT_PMDS * PMD_SIZE) | 99 | #define CONT_PMD_SIZE (CONT_PMDS * PMD_SIZE) |
| 100 | #define CONT_PMD_MASK (~(CONT_PMD_SIZE - 1)) | 100 | #define CONT_PMD_MASK (~(CONT_PMD_SIZE - 1)) |
| 101 | /* the the numerical offset of the PTE within a range of CONT_PTES */ | 101 | /* the numerical offset of the PTE within a range of CONT_PTES */ |
| 102 | #define CONT_RANGE_OFFSET(addr) (((addr)>>PAGE_SHIFT)&(CONT_PTES-1)) | 102 | #define CONT_RANGE_OFFSET(addr) (((addr)>>PAGE_SHIFT)&(CONT_PTES-1)) |
| 103 | 103 | ||
| 104 | /* | 104 | /* |
| @@ -178,10 +178,12 @@ · 73 unmodified lines | |||
| 178 | #define PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[2:1] */ | 178 | #define PTE_S2_RDONLY (_AT(pteval_t, 1) << 6) /* HAP[2:1] */ |
| 179 | #define PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ | 179 | #define PTE_S2_RDWR (_AT(pteval_t, 3) << 6) /* HAP[2:1] */ |
| 180 | #define PTE_S2_XN (_AT(pteval_t, 2) << 53) /* XN[1:0] */ | 180 | #define PTE_S2_XN (_AT(pteval_t, 2) << 53) /* XN[1:0] */ |
| 181 | #define PTE_S2_SW_RESVD (_AT(pteval_t, 15) << 55) /* Reserved for SW */ | ||
| 181 | 182 | ||
| 182 | #define PMD_S2_RDONLY (_AT(pmdval_t, 1) << 6) /* HAP[2:1] */ | 183 | #define PMD_S2_RDONLY (_AT(pmdval_t, 1) << 6) /* HAP[2:1] */ |
| 183 | #define PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */ | 184 | #define PMD_S2_RDWR (_AT(pmdval_t, 3) << 6) /* HAP[2:1] */ |
| 184 | #define PMD_S2_XN (_AT(pmdval_t, 2) << 53) /* XN[1:0] */ | 185 | #define PMD_S2_XN (_AT(pmdval_t, 2) << 53) /* XN[1:0] */ |
| 186 | #define PMD_S2_SW_RESVD (_AT(pmdval_t, 15) << 55) /* Reserved for SW */ | ||
| 185 | 187 | ||
| 186 | #define PUD_S2_RDONLY (_AT(pudval_t, 1) << 6) /* HAP[2:1] */ | 188 | #define PUD_S2_RDONLY (_AT(pudval_t, 1) << 6) /* HAP[2:1] */ |
| 187 | #define PUD_S2_RDWR (_AT(pudval_t, 3) << 6) /* HAP[2:1] */ | 189 | #define PUD_S2_RDWR (_AT(pudval_t, 3) << 6) /* HAP[2:1] */ |
| @@ -216,6 +218,7 @@ · 28 unmodified lines | |||
| 216 | #define TCR_TxSZ(x) (TCR_T0SZ(x) | TCR_T1SZ(x)) | 218 | #define TCR_TxSZ(x) (TCR_T0SZ(x) | TCR_T1SZ(x)) |
| 217 | #define TCR_TxSZ_WIDTH 6 | 219 | #define TCR_TxSZ_WIDTH 6 |
| 218 | #define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET) | 220 | #define TCR_T0SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T0SZ_OFFSET) |
| 221 | #define TCR_T1SZ_MASK (((UL(1) << TCR_TxSZ_WIDTH) - 1) << TCR_T1SZ_OFFSET) | ||
| 219 | 222 | ||
| 220 | #define TCR_EPD0_SHIFT 7 | 223 | #define TCR_EPD0_SHIFT 7 |
| 221 | #define TCR_EPD0_MASK (UL(1) << TCR_EPD0_SHIFT) | 224 | #define TCR_EPD0_MASK (UL(1) << TCR_EPD0_SHIFT) |
| @@ -40,6 +40,16 @@ extern void __pmd_error(const char *file, int line, unsigned long val); · 39 unmodified lines | |||
| 40 | extern void __pud_error(const char *file, int line, unsigned long val); | 40 | extern void __pud_error(const char *file, int line, unsigned long val); |
| 41 | extern void __pgd_error(const char *file, int line, unsigned long val); | 41 | extern void __pgd_error(const char *file, int line, unsigned long val); |
| 42 | 42 | ||
| 43 | #ifdef CONFIG_TRANSPARENT_HUGEPAGE | ||
| 44 | #define __HAVE_ARCH_FLUSH_PMD_TLB_RANGE | ||
| 45 | |||
| 46 | /* Set stride and tlb_level in flush_*_tlb_range */ | ||
| 47 | #define flush_pmd_tlb_range(vma, addr, end) \ | ||
| 48 | __flush_tlb_range(vma, addr, end, PMD_SIZE, false, 2) | ||
| 49 | #define flush_pud_tlb_range(vma, addr, end) \ | ||
| 50 | __flush_tlb_range(vma, addr, end, PUD_SIZE, false, 1) | ||
| 51 | #endif /* CONFIG_TRANSPARENT_HUGEPAGE */ | ||
| 52 | |||
| 43 | /* | 53 | /* |
| 44 | * ZERO_PAGE is a global shared page that is always zero: used | 54 | * ZERO_PAGE is a global shared page that is always zero: used |
| 45 | * for zero-mapped memory areas etc.. | 55 | * for zero-mapped memory areas etc.. |
| @@ -27,7 +27,7 @@ · 26 unmodified lines | |||
| 27 | * | 27 | * |
| 28 | * Some code sections either automatically switch back to PSR.I or explicitly | 28 | * Some code sections either automatically switch back to PSR.I or explicitly |
| 29 | * require to not use priority masking. If bit GIC_PRIO_PSR_I_SET is included | 29 | * require to not use priority masking. If bit GIC_PRIO_PSR_I_SET is included |
| 30 | * in the the priority mask, it indicates that PSR.I should be set and | 30 | * in the priority mask, it indicates that PSR.I should be set and |
| 31 | * interrupt disabling temporarily does not rely on IRQ priorities. | 31 | * interrupt disabling temporarily does not rely on IRQ priorities. |
| 32 | */ | 32 | */ |
| 33 | #define GIC_PRIO_IRQON 0xe0 | 33 | #define GIC_PRIO_IRQON 0xe0 |
| @@ -256,4 +256,13 @@ stage2_pgd_addr_end(struct kvm *kvm, phys_addr_t addr, phys_addr_t end) · 255 unmodified lines | |||
| 256 | return (boundary - 1 < end - 1) ? boundary : end; | 256 | return (boundary - 1 < end - 1) ? boundary : end; |
| 257 | } | 257 | } |
| 258 | 258 | ||
| 259 | /* | ||
| 260 | * Level values for the ARMv8.4-TTL extension, mapping PUD/PMD/PTE and | ||
| 261 | * the architectural page-table level. | ||
| 262 | */ | ||
| 263 | #define S2_NO_LEVEL_HINT 0 | ||
| 264 | #define S2_PUD_LEVEL 1 | ||
| 265 | #define S2_PMD_LEVEL 2 | ||
| 266 | #define S2_PTE_LEVEL 3 | ||
| 267 | |||
| 259 | #endif /* __ARM64_S2_PGTABLE_H_ */ | 268 | #endif /* __ARM64_S2_PGTABLE_H_ */ |
| @@ -421,9 +421,9 @@ · 420 unmodified lines | |||
| 421 | */ | 421 | */ |
| 422 | 422 | ||
| 423 | #define SYS_AMEVCNTR0_EL0(n) SYS_AM_EL0(4 + ((n) >> 3), (n) & 7) | 423 | #define SYS_AMEVCNTR0_EL0(n) SYS_AM_EL0(4 + ((n) >> 3), (n) & 7) |
| 424 | #define SYS_AMEVTYPE0_EL0(n) SYS_AM_EL0(6 + ((n) >> 3), (n) & 7) | 424 | #define SYS_AMEVTYPER0_EL0(n) SYS_AM_EL0(6 + ((n) >> 3), (n) & 7) |
| 425 | #define SYS_AMEVCNTR1_EL0(n) SYS_AM_EL0(12 + ((n) >> 3), (n) & 7) | 425 | #define SYS_AMEVCNTR1_EL0(n) SYS_AM_EL0(12 + ((n) >> 3), (n) & 7) |
| 426 | #define SYS_AMEVTYPE1_EL0(n) SYS_AM_EL0(14 + ((n) >> 3), (n) & 7) | 426 | #define SYS_AMEVTYPER1_EL0(n) SYS_AM_EL0(14 + ((n) >> 3), (n) & 7) |
| 427 | 427 | ||
| 428 | /* AMU v1: Fixed (architecturally defined) activity monitors */ | 428 | /* AMU v1: Fixed (architecturally defined) activity monitors */ |
| 429 | #define SYS_AMEVCNTR0_CORE_EL0 SYS_AMEVCNTR0_EL0(0) | 429 | #define SYS_AMEVCNTR0_CORE_EL0 SYS_AMEVCNTR0_EL0(0) |
| @@ -617,6 +617,9 @@ · 187 unmodified lines | |||
| 617 | #define ID_AA64ISAR0_SHA1_SHIFT 8 | 617 | #define ID_AA64ISAR0_SHA1_SHIFT 8 |
| 618 | #define ID_AA64ISAR0_AES_SHIFT 4 | 618 | #define ID_AA64ISAR0_AES_SHIFT 4 |
| 619 | 619 | ||
| 620 | #define ID_AA64ISAR0_TLB_RANGE_NI 0x0 | ||
| 621 | #define ID_AA64ISAR0_TLB_RANGE 0x2 | ||
| 622 | |||
| 620 | /* id_aa64isar1 */ | 623 | /* id_aa64isar1 */ |
| 621 | #define ID_AA64ISAR1_I8MM_SHIFT 52 | 624 | #define ID_AA64ISAR1_I8MM_SHIFT 52 |
| 622 | #define ID_AA64ISAR1_DGH_SHIFT 48 | 625 | #define ID_AA64ISAR1_DGH_SHIFT 48 |
| @@ -706,6 +709,9 @@ · 83 unmodified lines | |||
| 706 | #define ID_AA64ZFR0_SVEVER_SVE2 0x1 | 709 | #define ID_AA64ZFR0_SVEVER_SVE2 0x1 |
| 707 | 710 | ||
| 708 | /* id_aa64mmfr0 */ | 711 | /* id_aa64mmfr0 */ |
| 712 | #define ID_AA64MMFR0_ECV_SHIFT 60 | ||
| 713 | #define ID_AA64MMFR0_FGT_SHIFT 56 | ||
| 714 | #define ID_AA64MMFR0_EXS_SHIFT 44 | ||
| 709 | #define ID_AA64MMFR0_TGRAN4_2_SHIFT 40 | 715 | #define ID_AA64MMFR0_TGRAN4_2_SHIFT 40 |
| 710 | #define ID_AA64MMFR0_TGRAN64_2_SHIFT 36 | 716 | #define ID_AA64MMFR0_TGRAN64_2_SHIFT 36 |
| 711 | #define ID_AA64MMFR0_TGRAN16_2_SHIFT 32 | 717 | #define ID_AA64MMFR0_TGRAN16_2_SHIFT 32 |
| @@ -734,6 +740,10 @@ · 22 unmodified lines | |||
| 734 | #endif | 740 | #endif |
| 735 | 741 | ||
| 736 | /* id_aa64mmfr1 */ | 742 | /* id_aa64mmfr1 */ |
| 743 | #define ID_AA64MMFR1_ETS_SHIFT 36 | ||
| 744 | #define ID_AA64MMFR1_TWED_SHIFT 32 | ||
| 745 | #define ID_AA64MMFR1_XNX_SHIFT 28 | ||
| 746 | #define ID_AA64MMFR1_SPECSEI_SHIFT 24 | ||
| 737 | #define ID_AA64MMFR1_PAN_SHIFT 20 | 747 | #define ID_AA64MMFR1_PAN_SHIFT 20 |
| 738 | #define ID_AA64MMFR1_LOR_SHIFT 16 | 748 | #define ID_AA64MMFR1_LOR_SHIFT 16 |
| 739 | #define ID_AA64MMFR1_HPD_SHIFT 12 | 749 | #define ID_AA64MMFR1_HPD_SHIFT 12 |
| @@ -746,8 +756,15 @@ · 6 unmodified lines | |||
| 746 | 756 | ||
| 747 | /* id_aa64mmfr2 */ | 757 | /* id_aa64mmfr2 */ |
| 748 | #define ID_AA64MMFR2_E0PD_SHIFT 60 | 758 | #define ID_AA64MMFR2_E0PD_SHIFT 60 |
| 759 | #define ID_AA64MMFR2_EVT_SHIFT 56 | ||
| 760 | #define ID_AA64MMFR2_BBM_SHIFT 52 | ||
| 761 | #define ID_AA64MMFR2_TTL_SHIFT 48 | ||
| 749 | #define ID_AA64MMFR2_FWB_SHIFT 40 | 762 | #define ID_AA64MMFR2_FWB_SHIFT 40 |
| 763 | #define ID_AA64MMFR2_IDS_SHIFT 36 | ||
| 750 | #define ID_AA64MMFR2_AT_SHIFT 32 | 764 | #define ID_AA64MMFR2_AT_SHIFT 32 |
| 765 | #define ID_AA64MMFR2_ST_SHIFT 28 | ||
| 766 | #define ID_AA64MMFR2_NV_SHIFT 24 | ||
| 767 | #define ID_AA64MMFR2_CCIDX_SHIFT 20 | ||
| 751 | #define ID_AA64MMFR2_LVA_SHIFT 16 | 768 | #define ID_AA64MMFR2_LVA_SHIFT 16 |
| 752 | #define ID_AA64MMFR2_IESB_SHIFT 12 | 769 | #define ID_AA64MMFR2_IESB_SHIFT 12 |
| 753 | #define ID_AA64MMFR2_LSM_SHIFT 8 | 770 | #define ID_AA64MMFR2_LSM_SHIFT 8 |
| @@ -755,6 +772,7 @@ · 1 unmodified line | |||
| 755 | #define ID_AA64MMFR2_CNP_SHIFT 0 | 772 | #define ID_AA64MMFR2_CNP_SHIFT 0 |
| 756 | 773 | ||
| 757 | /* id_aa64dfr0 */ | 774 | /* id_aa64dfr0 */ |
| 775 | #define ID_AA64DFR0_DOUBLELOCK_SHIFT 36 | ||
| 758 | #define ID_AA64DFR0_PMSVER_SHIFT 32 | 776 | #define ID_AA64DFR0_PMSVER_SHIFT 32 |
| 759 | #define ID_AA64DFR0_CTX_CMPS_SHIFT 28 | 777 | #define ID_AA64DFR0_CTX_CMPS_SHIFT 28 |
| 760 | #define ID_AA64DFR0_WRPS_SHIFT 20 | 778 | #define ID_AA64DFR0_WRPS_SHIFT 20 |
| @@ -807,18 +825,40 @@ · 46 unmodified lines | |||
| 807 | #define ID_ISAR6_DP_SHIFT 4 | 825 | #define ID_ISAR6_DP_SHIFT 4 |
| 808 | #define ID_ISAR6_JSCVT_SHIFT 0 | 826 | #define ID_ISAR6_JSCVT_SHIFT 0 |
| 809 | 827 | ||
| 828 | #define ID_MMFR0_INNERSHR_SHIFT 28 | ||
| 829 | #define ID_MMFR0_FCSE_SHIFT 24 | ||
| 830 | #define ID_MMFR0_AUXREG_SHIFT 20 | ||
| 831 | #define ID_MMFR0_TCM_SHIFT 16 | ||
| 832 | #define ID_MMFR0_SHARELVL_SHIFT 12 | ||
| 833 | #define ID_MMFR0_OUTERSHR_SHIFT 8 | ||
| 834 | #define ID_MMFR0_PMSA_SHIFT 4 | ||
| 835 | #define ID_MMFR0_VMSA_SHIFT 0 | ||
| 836 | |||
| 810 | #define ID_MMFR4_EVT_SHIFT 28 | 837 | #define ID_MMFR4_EVT_SHIFT 28 |
| 811 | #define ID_MMFR4_CCIDX_SHIFT 24 | 838 | #define ID_MMFR4_CCIDX_SHIFT 24 |
| 812 | #define ID_MMFR4_LSM_SHIFT 20 | 839 | #define ID_MMFR4_LSM_SHIFT 20 |
| 813 | #define ID_MMFR4_HPDS_SHIFT 16 | 840 | #define ID_MMFR4_HPDS_SHIFT 16 |
| 814 | #define ID_MMFR4_CNP_SHIFT 12 | 841 | #define ID_MMFR4_CNP_SHIFT 12 |
| 815 | #define ID_MMFR4_XNX_SHIFT 8 | 842 | #define ID_MMFR4_XNX_SHIFT 8 |
| 843 | #define ID_MMFR4_AC2_SHIFT 4 | ||
| 816 | #define ID_MMFR4_SPECSEI_SHIFT 0 | 844 | #define ID_MMFR4_SPECSEI_SHIFT 0 |
| 817 | 845 | ||
| 818 | #define ID_MMFR5_ETS_SHIFT 0 | 846 | #define ID_MMFR5_ETS_SHIFT 0 |
| 819 | 847 | ||
| 820 | #define ID_PFR0_DIT_SHIFT 24 | 848 | #define ID_PFR0_DIT_SHIFT 24 |
| 821 | #define ID_PFR0_CSV2_SHIFT 16 | 849 | #define ID_PFR0_CSV2_SHIFT 16 |
| 850 | #define ID_PFR0_STATE3_SHIFT 12 | ||
| 851 | #define ID_PFR0_STATE2_SHIFT 8 | ||
| 852 | #define ID_PFR0_STATE1_SHIFT 4 | ||
| 853 | #define ID_PFR0_STATE0_SHIFT 0 | ||
| 854 | |||
| 855 | #define ID_DFR0_PERFMON_SHIFT 24 | ||
| 856 | #define ID_DFR0_MPROFDBG_SHIFT 20 | ||
| 857 | #define ID_DFR0_MMAPTRC_SHIFT 16 | ||
| 858 | #define ID_DFR0_COPTRC_SHIFT 12 | ||
| 859 | #define ID_DFR0_MMAPDBG_SHIFT 8 | ||
| 860 | #define ID_DFR0_COPSDBG_SHIFT 4 | ||
| 861 | #define ID_DFR0_COPDBG_SHIFT 0 | ||
| 822 | 862 | ||
| 823 | #define ID_PFR2_SSBS_SHIFT 4 | 863 | #define ID_PFR2_SSBS_SHIFT 4 |
| 824 | #define ID_PFR2_CSV3_SHIFT 0 | 864 | #define ID_PFR2_CSV3_SHIFT 0 |
| @@ -861,6 +901,11 @@ · 36 unmodified lines | |||
| 861 | #define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN64_SUPPORTED | 901 | #define ID_AA64MMFR0_TGRAN_SUPPORTED ID_AA64MMFR0_TGRAN64_SUPPORTED |
| 862 | #endif | 902 | #endif |
| 863 | 903 | ||
| 904 | #define MVFR2_FPMISC_SHIFT 4 | ||
| 905 | #define MVFR2_SIMDMISC_SHIFT 0 | ||
| 906 | |||
| 907 | #define DCZID_DZP_SHIFT 4 | ||
| 908 | #define DCZID_BS_SHIFT 0 | ||
| 864 | 909 | ||
| 865 | /* | 910 | /* |
| 866 | * The ZCR_ELx_LEN_* definitions intentionally include bits [8:4] which | 911 | * The ZCR_ELx_LEN_* definitions intentionally include bits [8:4] which |
| @@ -21,11 +21,37 @@ static void tlb_flush(struct mmu_gather *tlb); · 20 unmodified lines | |||
| 21 | 21 | ||
| 22 | #include <asm-generic/tlb.h> | 22 | #include <asm-generic/tlb.h> |
| 23 | 23 | ||
| 24 | /* | ||
| 25 | * get the tlbi levels in arm64. Default value is 0 if more than one | ||
| 26 | * of cleared_* is set or neither is set. | ||
| 27 | * Arm64 doesn't support p4ds now. | ||
| 28 | */ | ||
| 29 | static inline int tlb_get_level(struct mmu_gather *tlb) | ||
| 30 | { | ||
| 31 | if (tlb->cleared_ptes && !(tlb->cleared_pmds || | ||
| 32 | tlb->cleared_puds || | ||
| 33 | tlb->cleared_p4ds)) | ||
| 34 | return 3; | ||
| 35 | |||
| 36 | if (tlb->cleared_pmds && !(tlb->cleared_ptes || | ||
| 37 | tlb->cleared_puds || | ||
| 38 | tlb->cleared_p4ds)) | ||
| 39 | return 2; | ||
| 40 | |||
| 41 | if (tlb->cleared_puds && !(tlb->cleared_ptes || | ||
| 42 | tlb->cleared_pmds || | ||
| 43 | tlb->cleared_p4ds)) | ||
| 44 | return 1; | ||
| 45 | |||
| 46 | return 0; | ||
| 47 | } | ||
| 48 | |||
| 24 | static inline void tlb_flush(struct mmu_gather *tlb) | 49 | static inline void tlb_flush(struct mmu_gather *tlb) |
| 25 | { | 50 | { |
| 26 | struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0); | 51 | struct vm_area_struct vma = TLB_FLUSH_VMA(tlb->mm, 0); |
| 27 | bool last_level = !tlb->freed_tables; | 52 | bool last_level = !tlb->freed_tables; |
| 28 | unsigned long stride = tlb_get_unmap_size(tlb); | 53 | unsigned long stride = tlb_get_unmap_size(tlb); |
| 54 | int tlb_level = tlb_get_level(tlb); | ||
| 29 | 55 | ||
| 30 | /* | 56 | /* |
| 31 | * If we're tearing down the address space then we only care about | 57 | * If we're tearing down the address space then we only care about |
| @@ -38,7 +64,8 @@ static inline void tlb_flush(struct mmu_gather *tlb) · 6 unmodified lines | |||
| 38 | return; | 64 | return; |
| 39 | } | 65 | } |
| 40 | 66 | ||
| 41 | __flush_tlb_range(&vma, tlb->start, tlb->end, stride, last_level); | 67 | __flush_tlb_range(&vma, tlb->start, tlb->end, stride, |
| 68 | last_level, tlb_level); | ||
| 42 | } | 69 | } |
| 43 | 70 | ||
| 44 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, | 71 | static inline void __pte_free_tlb(struct mmu_gather *tlb, pgtable_t pte, |
| @@ -10,6 +10,7 @@ · 9 unmodified lines | |||
| 10 | 10 | ||
| 11 | #ifndef __ASSEMBLY__ | 11 | #ifndef __ASSEMBLY__ |
| 12 | 12 | ||
| 13 | #include <linux/bitfield.h> | ||
| 13 | #include <linux/mm_types.h> | 14 | #include <linux/mm_types.h> |
| 14 | #include <linux/sched.h> | 15 | #include <linux/sched.h> |
| 15 | #include <asm/cputype.h> | 16 | #include <asm/cputype.h> |
| @@ -59,6 +60,102 @@ · 43 unmodified lines | |||
| 59 | __ta; \ | 60 | __ta; \ |
| 60 | }) | 61 | }) |
| 61 | 62 | ||
| 63 | /* | ||
| 64 | * Get translation granule of the system, which is decided by | ||
| 65 | * PAGE_SIZE. Used by TTL. | ||
| 66 | * - 4KB : 1 | ||
| 67 | * - 16KB : 2 | ||
| 68 | * - 64KB : 3 | ||
| 69 | */ | ||
| 70 | #define TLBI_TTL_TG_4K 1 | ||
| 71 | #define TLBI_TTL_TG_16K 2 | ||
| 72 | #define TLBI_TTL_TG_64K 3 | ||
| 73 | |||
| 74 | static inline unsigned long get_trans_granule(void) | ||
| 75 | { | ||
| 76 | switch (PAGE_SIZE) { | ||
| 77 | case SZ_4K: | ||
| 78 | return TLBI_TTL_TG_4K; | ||
| 79 | case SZ_16K: | ||
| 80 | return TLBI_TTL_TG_16K; | ||
| 81 | case SZ_64K: | ||
| 82 | return TLBI_TTL_TG_64K; | ||
| 83 | default: | ||
| 84 | return 0; | ||
| 85 | } | ||
| 86 | } | ||
| 87 | |||
| 88 | /* | ||
| 89 | * Level-based TLBI operations. | ||
| 90 | * | ||
| 91 | * When ARMv8.4-TTL exists, TLBI operations take an additional hint for | ||
| 92 | * the level at which the invalidation must take place. If the level is | ||
| 93 | * wrong, no invalidation may take place. In the case where the level | ||
| 94 | * cannot be easily determined, a 0 value for the level parameter will | ||
| 95 | * perform a non-hinted invalidation. | ||
| 96 | * | ||
| 97 | * For Stage-2 invalidation, use the level values provided to that effect | ||
| 98 | * in asm/stage2_pgtable.h. | ||
| 99 | */ | ||
| 100 | #define TLBI_TTL_MASK GENMASK_ULL(47, 44) | ||
| 101 | |||
| 102 | #define __tlbi_level(op, addr, level) do { \ | ||
| 103 | u64 arg = addr; \ | ||
| 104 | \ | ||
| 105 | if (cpus_have_const_cap(ARM64_HAS_ARMv8_4_TTL) && \ | ||
| 106 | level) { \ | ||
| 107 | u64 ttl = level & 3; \ | ||
| 108 | ttl |= get_trans_granule() << 2; \ | ||
| 109 | arg &= ~TLBI_TTL_MASK; \ | ||
| 110 | arg |= FIELD_PREP(TLBI_TTL_MASK, ttl); \ | ||
| 111 | } \ | ||
| 112 | \ | ||
| 113 | __tlbi(op, arg); \ | ||
| 114 | } while(0) | ||
| 115 | |||
| 116 | #define __tlbi_user_level(op, arg, level) do { \ | ||
| 117 | if (arm64_kernel_unmapped_at_el0()) \ | ||
| 118 | __tlbi_level(op, (arg | USER_ASID_FLAG), level); \ | ||
| 119 | } while (0) | ||
| 120 | |||
| 121 | /* | ||
| 122 | * This macro creates a properly formatted VA operand for the TLB RANGE. | ||
| 123 | * The value bit assignments are: | ||
| 124 | * | ||
| 125 | * +----------+------+-------+-------+-------+----------------------+ | ||
| 126 | * | ASID | TG | SCALE | NUM | TTL | BADDR | | ||
| 127 | * +-----------------+-------+-------+-------+----------------------+ | ||
| 128 | * |63 48|47 46|45 44|43 39|38 37|36 0| | ||
| 129 | * | ||
| 130 | * The address range is determined by below formula: | ||
| 131 | * [BADDR, BADDR + (NUM + 1) * 2^(5*SCALE + 1) * PAGESIZE) | ||
| 132 | * | ||
| 133 | */ | ||
| 134 | #define __TLBI_VADDR_RANGE(addr, asid, scale, num, ttl) \ | ||
| 135 | ({ \ | ||
| 136 | unsigned long __ta = (addr) >> PAGE_SHIFT; \ | ||
| 137 | __ta &= GENMASK_ULL(36, 0); \ | ||
| 138 | __ta |= (unsigned long)(ttl) << 37; \ | ||
| 139 | __ta |= (unsigned long)(num) << 39; \ | ||
| 140 | __ta |= (unsigned long)(scale) << 44; \ | ||
| 141 | __ta |= get_trans_granule() << 46; \ | ||
| 142 | __ta |= (unsigned long)(asid) << 48; \ | ||
| 143 | __ta; \ | ||
| 144 | }) | ||
| 145 | |||
| 146 | /* These macros are used by the TLBI RANGE feature. */ | ||
| 147 | #define __TLBI_RANGE_PAGES(num, scale) \ | ||
| 148 | ((unsigned long)((num) + 1) << (5 * (scale) + 1)) | ||
| 149 | #define MAX_TLBI_RANGE_PAGES __TLBI_RANGE_PAGES(31, 3) | ||
| 150 | |||
| 151 | /* | ||
| 152 | * Generate 'num' values from -1 to 30 with -1 rejected by the | ||
| 153 | * __flush_tlb_range() loop below. | ||
| 154 | */ | ||
| 155 | #define TLBI_RANGE_MASK GENMASK_ULL(4, 0) | ||
| 156 | #define __TLBI_RANGE_NUM(pages, scale) \ | ||
| 157 | ((((pages) >> (5 * (scale) + 1)) & TLBI_RANGE_MASK) - 1) | ||
| 158 | |||
| 62 | /* | 159 | /* |
| 63 | * TLB Invalidation | 160 | * TLB Invalidation |
| 64 | * ================ | 161 | * ================ |
| @@ -179,34 +276,83 @@ static inline void flush_tlb_page(struct vm_area_struct *vma, · 114 unmodified lines | |||
| 179 | 276 | ||
| 180 | static inline void __flush_tlb_range(struct vm_area_struct *vma, | 277 | static inline void __flush_tlb_range(struct vm_area_struct *vma, |
| 181 | unsigned long start, unsigned long end, | 278 | unsigned long start, unsigned long end, |
| 182 | unsigned long stride, bool last_level) | 279 | unsigned long stride, bool last_level, |
| 280 | int tlb_level) | ||
| 183 | { | 281 | { |
| 282 | int num = 0; | ||
| 283 | int scale = 0; | ||
| 184 | unsigned long asid = ASID(vma->vm_mm); | 284 | unsigned long asid = ASID(vma->vm_mm); |
| 185 | unsigned long addr; | 285 | unsigned long addr; |
| 286 | unsigned long pages; | ||
| 186 | 287 | ||
| 187 | start = round_down(start, stride); | 288 | start = round_down(start, stride); |
| 188 | end = round_up(end, stride); | 289 | end = round_up(end, stride); |
| 290 | pages = (end - start) >> PAGE_SHIFT; | ||
| 189 | 291 | ||
| 190 | if ((end - start) >= (MAX_TLBI_OPS * stride)) { | 292 | /* |
| 293 | * When not uses TLB range ops, we can handle up to | ||
| 294 | * (MAX_TLBI_OPS - 1) pages; | ||
| 295 | * When uses TLB range ops, we can handle up to | ||
| 296 | * (MAX_TLBI_RANGE_PAGES - 1) pages. | ||
| 297 | */ | ||
| 298 | if ((!system_supports_tlb_range() && | ||
| 299 | (end - start) >= (MAX_TLBI_OPS * stride)) || | ||
| 300 | pages >= MAX_TLBI_RANGE_PAGES) { | ||
| 191 | flush_tlb_mm(vma->vm_mm); | 301 | flush_tlb_mm(vma->vm_mm); |
| 192 | return; | 302 | return; |
| 193 | } | 303 | } |
| 194 | 304 | ||
| 195 | /* Convert the stride into units of 4k */ | 305 | dsb(ishst); |
| 196 | stride >>= 12; | ||
| 197 | 306 | ||
| 198 | start = __TLBI_VADDR(start, asid); | 307 | /* |
| 199 | end = __TLBI_VADDR(end, asid); | 308 | * When the CPU does not support TLB range operations, flush the TLB |
| 309 | * entries one by one at the granularity of 'stride'. If the the TLB | ||
| 310 | * range ops are supported, then: | ||
| 311 | * | ||
| 312 | * 1. If 'pages' is odd, flush the first page through non-range | ||
| 313 | * operations; | ||
| 314 | * | ||
| 315 | * 2. For remaining pages: the minimum range granularity is decided | ||
| 316 | * by 'scale', so multiple range TLBI operations may be required. | ||
| 317 | * Start from scale = 0, flush the corresponding number of pages | ||
| 318 | * ((num+1)*2^(5*scale+1) starting from 'addr'), then increase it | ||
| 319 | * until no pages left. | ||
| 320 | * | ||
| 321 | * Note that certain ranges can be represented by either num = 31 and | ||
| 322 | * scale or num = 0 and scale + 1. The loop below favours the latter | ||
| 323 | * since num is limited to 30 by the __TLBI_RANGE_NUM() macro. | ||
| 324 | */ | ||
| 325 | while (pages > 0) { | ||
| 326 | if (!system_supports_tlb_range() || | ||
| 327 | pages % 2 == 1) { | ||
| 328 | addr = __TLBI_VADDR(start, asid); | ||
| 329 | if (last_level) { | ||
| 330 | __tlbi_level(vale1is, addr, tlb_level); | ||
| 331 | __tlbi_user_level(vale1is, addr, tlb_level); | ||
| 332 | } else { | ||
| 333 | __tlbi_level(vae1is, addr, tlb_level); | ||
| 334 | __tlbi_user_level(vae1is, addr, tlb_level); | ||
| 335 | } | ||
| 336 | start += stride; | ||
| 337 | pages -= stride >> PAGE_SHIFT; | ||
| 338 | continue; | ||
| 339 | } | ||
| 200 | 340 | ||
| 201 | dsb(ishst); | 341 | num = __TLBI_RANGE_NUM(pages, scale); |
| 202 | for (addr = start; addr < end; addr += stride) { | 342 | if (num >= 0) { |
| 203 | if (last_level) { | 343 | addr = __TLBI_VADDR_RANGE(start, asid, scale, |
| 204 | __tlbi(vale1is, addr); | 344 | num, tlb_level); |
| 205 | __tlbi_user(vale1is, addr); | 345 | if (last_level) { |
| 206 | } else { | 346 | __tlbi(rvale1is, addr); |
| 207 | __tlbi(vae1is, addr); | 347 | __tlbi_user(rvale1is, addr); |
| 208 | __tlbi_user(vae1is, addr); | 348 | } else { |
| 349 | __tlbi(rvae1is, addr); | ||
| 350 | __tlbi_user(rvae1is, addr); | ||
| 351 | } | ||
| 352 | start += __TLBI_RANGE_PAGES(num, scale) << PAGE_SHIFT; | ||
| 353 | pages -= __TLBI_RANGE_PAGES(num, scale); | ||
| 209 | } | 354 | } |
| 355 | scale++; | ||
| 210 | } | 356 | } |
| 211 | dsb(ish); | 357 | dsb(ish); |
| 212 | } | 358 | } |
| @@ -217,8 +363,9 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, · 4 unmodified lines | |||
| 217 | /* | 363 | /* |
| 218 | * We cannot use leaf-only invalidation here, since we may be invalidating | 364 | * We cannot use leaf-only invalidation here, since we may be invalidating |
| 219 | * table entries as part of collapsing hugepages or moving page tables. | 365 | * table entries as part of collapsing hugepages or moving page tables. |
| 366 | * Set the tlb_level to 0 because we can not get enough information here. | ||
| 220 | */ | 367 | */ |
| 221 | __flush_tlb_range(vma, start, end, PAGE_SIZE, false); | 368 | __flush_tlb_range(vma, start, end, PAGE_SIZE, false, 0); |
| 222 | } | 369 | } |
| 223 | 370 | ||
| 224 | static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) | 371 | static inline void flush_tlb_kernel_range(unsigned long start, unsigned long end) |
| @@ -19,6 +19,7 @@ · 18 unmodified lines | |||
| 19 | #include <linux/string.h> | 19 | #include <linux/string.h> |
| 20 | 20 | ||
| 21 | #include <asm/cpufeature.h> | 21 | #include <asm/cpufeature.h> |
| 22 | #include <asm/mmu.h> | ||
| 22 | #include <asm/ptrace.h> | 23 | #include <asm/ptrace.h> |
| 23 | #include <asm/memory.h> | 24 | #include <asm/memory.h> |
| 24 | #include <asm/extable.h> | 25 | #include <asm/extable.h> |
| @@ -12,6 +12,8 @@ · 11 unmodified lines | |||
| 12 | */ | 12 | */ |
| 13 | #define VDSO_LBASE 0x0 | 13 | #define VDSO_LBASE 0x0 |
| 14 | 14 | ||
| 15 | #define __VVAR_PAGES 2 | ||
| 16 | |||
| 15 | #ifndef __ASSEMBLY__ | 17 | #ifndef __ASSEMBLY__ |
| 16 | 18 | ||
| 17 | #include <generated/vdso-offsets.h> | 19 | #include <generated/vdso-offsets.h> |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #ifndef __ASSEMBLY__ | 8 | #ifndef __ASSEMBLY__ |
| 9 | 9 | ||
| 10 | #include <asm/barrier.h> | ||
| 10 | #include <asm/unistd.h> | 11 | #include <asm/unistd.h> |
| 11 | #include <asm/errno.h> | 12 | #include <asm/errno.h> |
| 12 | 13 | ||
| @@ -152,6 +153,18 @@ static __always_inline const struct vdso_data *__arch_get_vdso_data(void) · 139 unmodified lines | |||
| 152 | return ret; | 153 | return ret; |
| 153 | } | 154 | } |
| 154 | 155 | ||
| 156 | #ifdef CONFIG_TIME_NS | ||
| 157 | static __always_inline const struct vdso_data *__arch_get_timens_vdso_data(void) | ||
| 158 | { | ||
| 159 | const struct vdso_data *ret; | ||
| 160 | |||
| 161 | /* See __arch_get_vdso_data(). */ | ||
| 162 | asm volatile("mov %0, %1" : "=r"(ret) : "r"(_timens_data)); | ||
| 163 | |||
| 164 | return ret; | ||
| 165 | } | ||
| 166 | #endif | ||
| 167 | |||
| 155 | static inline bool vdso_clocksource_ok(const struct vdso_data *vd) | 168 | static inline bool vdso_clocksource_ok(const struct vdso_data *vd) |
| 156 | { | 169 | { |
| 157 | return vd->clock_mode == VDSO_CLOCKMODE_ARCHTIMER; | 170 | return vd->clock_mode == VDSO_CLOCKMODE_ARCHTIMER; |
| @@ -7,6 +7,7 @@ · 6 unmodified lines | |||
| 7 | 7 | ||
| 8 | #ifndef __ASSEMBLY__ | 8 | #ifndef __ASSEMBLY__ |
| 9 | 9 | ||
| 10 | #include <asm/barrier.h> | ||
| 10 | #include <asm/unistd.h> | 11 | #include <asm/unistd.h> |
| 11 | 12 | ||
| 12 | #define VDSO_HAS_CLOCK_GETRES 1 | 13 | #define VDSO_HAS_CLOCK_GETRES 1 |
| @@ -96,6 +97,14 @@ const struct vdso_data *__arch_get_vdso_data(void) · 83 unmodified lines | |||
| 96 | return _vdso_data; | 97 | return _vdso_data; |
| 97 | } | 98 | } |
| 98 | 99 | ||
| 100 | #ifdef CONFIG_TIME_NS | ||
| 101 | static __always_inline | ||
| 102 | const struct vdso_data *__arch_get_timens_vdso_data(void) | ||
| 103 | { | ||
| 104 | return _timens_data; | ||
| 105 | } | ||
| 106 | #endif | ||
| 107 | |||
| 99 | #endif /* !__ASSEMBLY__ */ | 108 | #endif /* !__ASSEMBLY__ */ |
| 100 | 109 | ||
| 101 | #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ | 110 | #endif /* __ASM_VDSO_GETTIMEOFDAY_H */ |
| @@ -74,5 +74,6 @@ · 73 unmodified lines | |||
| 74 | #define HWCAP2_DGH (1 << 15) | 74 | #define HWCAP2_DGH (1 << 15) |
| 75 | #define HWCAP2_RNG (1 << 16) | 75 | #define HWCAP2_RNG (1 << 16) |
| 76 | #define HWCAP2_BTI (1 << 17) | 76 | #define HWCAP2_BTI (1 << 17) |
| 77 | /* reserved for HWCAP2_MTE (1 << 18) */ | ||
| 77 | 78 | ||
| 78 | #endif /* _UAPI__ASM_HWCAP_H */ | 79 | #endif /* _UAPI__ASM_HWCAP_H */ |
| @@ -179,7 +179,7 @@ struct sve_context { · 178 unmodified lines | |||
| 179 | * The same convention applies when returning from a signal: a caller | 179 | * The same convention applies when returning from a signal: a caller |
| 180 | * will need to remove or resize the sve_context block if it wants to | 180 | * will need to remove or resize the sve_context block if it wants to |
| 181 | * make the SVE registers live when they were previously non-live or | 181 | * make the SVE registers live when they were previously non-live or |
| 182 | * vice-versa. This may require the the caller to allocate fresh | 182 | * vice-versa. This may require the caller to allocate fresh |
| 183 | * memory and/or move other context blocks in the signal frame. | 183 | * memory and/or move other context blocks in the signal frame. |
| 184 | * | 184 | * |
| 185 | * Changing the vector length during signal return is not permitted: | 185 | * Changing the vector length during signal return is not permitted: |
| @@ -261,6 +261,81 @@ pgprot_t __acpi_get_mem_attribute(phys_addr_t addr) · 260 unmodified lines | |||
| 261 | return __pgprot(PROT_DEVICE_nGnRnE); | 261 | return __pgprot(PROT_DEVICE_nGnRnE); |
| 262 | } | 262 | } |
| 263 | 263 | ||
| 264 | void __iomem *acpi_os_ioremap(acpi_physical_address phys, acpi_size size) | ||
| 265 | { | ||
| 266 | efi_memory_desc_t *md, *region = NULL; | ||
| 267 | pgprot_t prot; | ||
| 268 | |||
| 269 | if (WARN_ON_ONCE(!efi_enabled(EFI_MEMMAP))) | ||
| 270 | return NULL; | ||
| 271 | |||
| 272 | for_each_efi_memory_desc(md) { | ||
| 273 | u64 end = md->phys_addr + (md->num_pages << EFI_PAGE_SHIFT); | ||
| 274 | |||
| 275 | if (phys < md->phys_addr || phys >= end) | ||
| 276 | continue; | ||
| 277 | |||
| 278 | if (phys + size > end) { | ||
| 279 | pr_warn(FW_BUG "requested region covers multiple EFI memory regions\n"); | ||
| 280 | return NULL; | ||
| 281 | } | ||
| 282 | region = md; | ||
| 283 | break; | ||
| 284 | } | ||
| 285 | |||
| 286 | /* | ||
| 287 | * It is fine for AML to remap regions that are not represented in the | ||
| 288 | * EFI memory map at all, as it only describes normal memory, and MMIO | ||
| 289 | * regions that require a virtual mapping to make them accessible to | ||
| 290 | * the EFI runtime services. | ||
| 291 | */ | ||
| 292 | prot = __pgprot(PROT_DEVICE_nGnRnE); | ||
| 293 | if (region) { | ||
| 294 | switch (region->type) { | ||
| 295 | case EFI_LOADER_CODE: | ||
| 296 | case EFI_LOADER_DATA: | ||
| 297 | case EFI_BOOT_SERVICES_CODE: | ||
| 298 | case EFI_BOOT_SERVICES_DATA: | ||
| 299 | case EFI_CONVENTIONAL_MEMORY: | ||
| 300 | case EFI_PERSISTENT_MEMORY: | ||
| 301 | pr_warn(FW_BUG "requested region covers kernel memory @ %pa\n", &phys); | ||
| 302 | return NULL; | ||
| 303 | |||
| 304 | case EFI_RUNTIME_SERVICES_CODE: | ||
| 305 | /* | ||
| 306 | * This would be unusual, but not problematic per se, | ||
| 307 | * as long as we take care not to create a writable | ||
| 308 | * mapping for executable code. | ||
| 309 | */ | ||
| 310 | prot = PAGE_KERNEL_RO; | ||
| 311 | break; | ||
| 312 | |||
| 313 | case EFI_ACPI_RECLAIM_MEMORY: | ||
| 314 | /* | ||
| 315 | * ACPI reclaim memory is used to pass firmware tables | ||
| 316 | * and other data that is intended for consumption by | ||
| 317 | * the OS only, which may decide it wants to reclaim | ||
| 318 | * that memory and use it for something else. We never | ||
| 319 | * do that, but we usually add it to the linear map | ||
| 320 | * anyway, in which case we should use the existing | ||
| 321 | * mapping. | ||
| 322 | */ | ||
| 323 | if (memblock_is_map_memory(phys)) | ||
| 324 | return (void __iomem *)__phys_to_virt(phys); | ||
| 325 | /* fall through */ | ||
| 326 | |||
| 327 | default: | ||
| 328 | if (region->attribute & EFI_MEMORY_WB) | ||
| 329 | prot = PAGE_KERNEL; | ||
| 330 | else if (region->attribute & EFI_MEMORY_WT) | ||
| 331 | prot = __pgprot(PROT_NORMAL_WT); | ||
| 332 | else if (region->attribute & EFI_MEMORY_WC) | ||
| 333 | prot = __pgprot(PROT_NORMAL_NC); | ||
| 334 | } | ||
| 335 | } | ||
| 336 | return __ioremap(phys, size, prot); | ||
| 337 | } | ||
| 338 | |||
| 264 | /* | 339 | /* |
| 265 | * Claim Synchronous External Aborts as a firmware first notification. | 340 | * Claim Synchronous External Aborts as a firmware first notification. |
| 266 | * | 341 | * |
| @@ -119,25 +119,12 @@ static inline void finalize_system_capabilities(void) · 118 unmodified lines | |||
| 119 | static_branch_enable(&arm64_const_caps_ready); | 119 | static_branch_enable(&arm64_const_caps_ready); |
| 120 | } | 120 | } |
| 121 | 121 | ||
| 122 | static int dump_cpu_hwcaps(struct notifier_block *self, unsigned long v, void *p) | 122 | void dump_cpu_features(void) |
| 123 | { | 123 | { |
| 124 | /* file-wide pr_fmt adds "CPU features: " prefix */ | 124 | /* file-wide pr_fmt adds "CPU features: " prefix */ |
| 125 | pr_emerg("0x%*pb\n", ARM64_NCAPS, &cpu_hwcaps); | 125 | pr_emerg("0x%*pb\n", ARM64_NCAPS, &cpu_hwcaps); |
| 126 | return 0; | ||
| 127 | } | 126 | } |
| 128 | 127 | ||
| 129 | static struct notifier_block cpu_hwcaps_notifier = { | ||
| 130 | .notifier_call = dump_cpu_hwcaps | ||
| 131 | }; | ||
| 132 | |||
| 133 | static int __init register_cpu_hwcaps_dumper(void) | ||
| 134 | { | ||
| 135 | atomic_notifier_chain_register(&panic_notifier_list, | ||
| 136 | &cpu_hwcaps_notifier); | ||
| 137 | return 0; | ||
| 138 | } | ||
| 139 | __initcall(register_cpu_hwcaps_dumper); | ||
| 140 | |||
| 141 | DEFINE_STATIC_KEY_ARRAY_FALSE(cpu_hwcap_keys, ARM64_NCAPS); | 128 | DEFINE_STATIC_KEY_ARRAY_FALSE(cpu_hwcap_keys, ARM64_NCAPS); |
| 142 | EXPORT_SYMBOL(cpu_hwcap_keys); | 129 | EXPORT_SYMBOL(cpu_hwcap_keys); |
| 143 | 130 | ||
| @@ -269,6 +256,9 @@ static const struct arm64_ftr_bits ftr_id_aa64zfr0[] = { · 125 unmodified lines | |||
| 269 | }; | 256 | }; |
| 270 | 257 | ||
| 271 | static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { | 258 | static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { |
| 259 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_ECV_SHIFT, 4, 0), | ||
| 260 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_FGT_SHIFT, 4, 0), | ||
| 261 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR0_EXS_SHIFT, 4, 0), | ||
| 272 | /* | 262 | /* |
| 273 | * Page size not being supported at Stage-2 is not fatal. You | 263 | * Page size not being supported at Stage-2 is not fatal. You |
| 274 | * just give up KVM if PAGE_SIZE isn't supported there. Go fix | 264 | * just give up KVM if PAGE_SIZE isn't supported there. Go fix |
| @@ -312,6 +302,10 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr0[] = { · 37 unmodified lines | |||
| 312 | }; | 302 | }; |
| 313 | 303 | ||
| 314 | static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { | 304 | static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { |
| 305 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_ETS_SHIFT, 4, 0), | ||
| 306 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_TWED_SHIFT, 4, 0), | ||
| 307 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_XNX_SHIFT, 4, 0), | ||
| 308 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_HIGHER_SAFE, ID_AA64MMFR1_SPECSEI_SHIFT, 4, 0), | ||
| 315 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_PAN_SHIFT, 4, 0), | 309 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_PAN_SHIFT, 4, 0), |
| 316 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_LOR_SHIFT, 4, 0), | 310 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_LOR_SHIFT, 4, 0), |
| 317 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_HPD_SHIFT, 4, 0), | 311 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR1_HPD_SHIFT, 4, 0), |
| @@ -323,8 +317,15 @@ static const struct arm64_ftr_bits ftr_id_aa64mmfr1[] = { · 5 unmodified lines | |||
| 323 | 317 | ||
| 324 | static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = { | 318 | static const struct arm64_ftr_bits ftr_id_aa64mmfr2[] = { |
| 325 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_E0PD_SHIFT, 4, 0), | 319 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_E0PD_SHIFT, 4, 0), |
| 320 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_EVT_SHIFT, 4, 0), | ||
| 321 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_BBM_SHIFT, 4, 0), | ||
| 322 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_TTL_SHIFT, 4, 0), | ||
| 326 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_FWB_SHIFT, 4, 0), | 323 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_FWB_SHIFT, 4, 0), |
| 324 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_IDS_SHIFT, 4, 0), | ||
| 327 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_AT_SHIFT, 4, 0), | 325 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_AT_SHIFT, 4, 0), |
| 326 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_ST_SHIFT, 4, 0), | ||
| 327 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_NV_SHIFT, 4, 0), | ||
| 328 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_CCIDX_SHIFT, 4, 0), | ||
| 328 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LVA_SHIFT, 4, 0), | 329 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LVA_SHIFT, 4, 0), |
| 329 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_IESB_SHIFT, 4, 0), | 330 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_IESB_SHIFT, 4, 0), |
| 330 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LSM_SHIFT, 4, 0), | 331 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64MMFR2_LSM_SHIFT, 4, 0), |
| @@ -345,7 +346,7 @@ static const struct arm64_ftr_bits ftr_ctr[] = { · 14 unmodified lines | |||
| 345 | * make use of *minLine. | 346 | * make use of *minLine. |
| 346 | * If we have differing I-cache policies, report it as the weakest - VIPT. | 347 | * If we have differing I-cache policies, report it as the weakest - VIPT. |
| 347 | */ | 348 | */ |
| 348 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_EXACT, 14, 2, ICACHE_POLICY_VIPT), /* L1Ip */ | 349 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_NONSTRICT, FTR_EXACT, CTR_L1IP_SHIFT, 2, ICACHE_POLICY_VIPT), /* L1Ip */ |
| 349 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_IMINLINE_SHIFT, 4, 0), | 350 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, CTR_IMINLINE_SHIFT, 4, 0), |
| 350 | ARM64_FTR_END, | 351 | ARM64_FTR_END, |
| 351 | }; | 352 | }; |
| @@ -356,19 +357,19 @@ struct arm64_ftr_reg arm64_ftr_reg_ctrel0 = { · 4 unmodified lines | |||
| 356 | }; | 357 | }; |
| 357 | 358 | ||
| 358 | static const struct arm64_ftr_bits ftr_id_mmfr0[] = { | 359 | static const struct arm64_ftr_bits ftr_id_mmfr0[] = { |
| 359 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 28, 4, 0xf), /* InnerShr */ | 360 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_INNERSHR_SHIFT, 4, 0xf), |
| 360 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0), /* FCSE */ | 361 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_FCSE_SHIFT, 4, 0), |
| 361 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, 20, 4, 0), /* AuxReg */ | 362 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_MMFR0_AUXREG_SHIFT, 4, 0), |
| 362 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 0), /* TCM */ | 363 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_TCM_SHIFT, 4, 0), |
| 363 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 12, 4, 0), /* ShareLvl */ | 364 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_SHARELVL_SHIFT, 4, 0), |
| 364 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 8, 4, 0xf), /* OuterShr */ | 365 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_OUTERSHR_SHIFT, 4, 0xf), |
| 365 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0), /* PMSA */ | 366 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_PMSA_SHIFT, 4, 0), |
| 366 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* VMSA */ | 367 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR0_VMSA_SHIFT, 4, 0), |
| 367 | ARM64_FTR_END, | 368 | ARM64_FTR_END, |
| 368 | }; | 369 | }; |
| 369 | 370 | ||
| 370 | static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { | 371 | static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { |
| 371 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 36, 4, 0), | 372 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_DOUBLELOCK_SHIFT, 4, 0), |
| 372 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_PMSVER_SHIFT, 4, 0), | 373 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64DFR0_PMSVER_SHIFT, 4, 0), |
| 373 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0), | 374 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_CTX_CMPS_SHIFT, 4, 0), |
| 374 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0), | 375 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64DFR0_WRPS_SHIFT, 4, 0), |
| @@ -384,14 +385,14 @@ static const struct arm64_ftr_bits ftr_id_aa64dfr0[] = { · 9 unmodified lines | |||
| 384 | }; | 385 | }; |
| 385 | 386 | ||
| 386 | static const struct arm64_ftr_bits ftr_mvfr2[] = { | 387 | static const struct arm64_ftr_bits ftr_mvfr2[] = { |
| 387 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0), /* FPMisc */ | 388 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_FPMISC_SHIFT, 4, 0), |
| 388 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* SIMDMisc */ | 389 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, MVFR2_SIMDMISC_SHIFT, 4, 0), |
| 389 | ARM64_FTR_END, | 390 | ARM64_FTR_END, |
| 390 | }; | 391 | }; |
| 391 | 392 | ||
| 392 | static const struct arm64_ftr_bits ftr_dczid[] = { | 393 | static const struct arm64_ftr_bits ftr_dczid[] = { |
| 393 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, 4, 1, 1), /* DZP */ | 394 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_EXACT, DCZID_DZP_SHIFT, 1, 1), |
| 394 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* BS */ | 395 | ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, DCZID_BS_SHIFT, 4, 0), |
| 395 | ARM64_FTR_END, | 396 | ARM64_FTR_END, |
| 396 | }; | 397 | }; |
| 397 | 398 | ||
| @@ -423,7 +424,8 @@ static const struct arm64_ftr_bits ftr_id_mmfr4[] = { · 25 unmodified lines | |||
| 423 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR4_HPDS_SHIFT, 4, 0), | 424 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR4_HPDS_SHIFT, 4, 0), |
| 424 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR4_CNP_SHIFT, 4, 0), | 425 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR4_CNP_SHIFT, 4, 0), |
| 425 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR4_XNX_SHIFT, 4, 0), | 426 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR4_XNX_SHIFT, 4, 0), |
| 426 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0), /* ac2 */ | 427 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_MMFR4_AC2_SHIFT, 4, 0), |
| 428 | |||
| 427 | /* | 429 | /* |
| 428 | * SpecSEI = 1 indicates that the PE might generate an SError on an | 430 | * SpecSEI = 1 indicates that the PE might generate an SError on an |
| 429 | * external abort on speculative read. It is safe to assume that an | 431 | * external abort on speculative read. It is safe to assume that an |
| @@ -465,10 +467,10 @@ static const struct arm64_ftr_bits ftr_id_isar6[] = { · 35 unmodified lines | |||
| 465 | static const struct arm64_ftr_bits ftr_id_pfr0[] = { | 467 | static const struct arm64_ftr_bits ftr_id_pfr0[] = { |
| 466 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_PFR0_DIT_SHIFT, 4, 0), | 468 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_PFR0_DIT_SHIFT, 4, 0), |
| 467 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_PFR0_CSV2_SHIFT, 4, 0), | 469 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_PFR0_CSV2_SHIFT, 4, 0), |
| 468 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 12, 4, 0), /* State3 */ | 470 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_PFR0_STATE3_SHIFT, 4, 0), |
| 469 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 8, 4, 0), /* State2 */ | 471 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_PFR0_STATE2_SHIFT, 4, 0), |
| 470 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0), /* State1 */ | 472 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_PFR0_STATE1_SHIFT, 4, 0), |
| 471 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), /* State0 */ | 473 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_PFR0_STATE0_SHIFT, 4, 0), |
| 472 | ARM64_FTR_END, | 474 | ARM64_FTR_END, |
| 473 | }; | 475 | }; |
| 474 | 476 | ||
| @@ -492,13 +494,13 @@ static const struct arm64_ftr_bits ftr_id_pfr2[] = { · 17 unmodified lines | |||
| 492 | 494 | ||
| 493 | static const struct arm64_ftr_bits ftr_id_dfr0[] = { | 495 | static const struct arm64_ftr_bits ftr_id_dfr0[] = { |
| 494 | /* [31:28] TraceFilt */ | 496 | /* [31:28] TraceFilt */ |
| 495 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 24, 4, 0xf), /* PerfMon */ | 497 | S_ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_PERFMON_SHIFT, 4, 0xf), |
| 496 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 20, 4, 0), | 498 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MPROFDBG_SHIFT, 4, 0), |
| 497 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 16, 4, 0), | 499 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MMAPTRC_SHIFT, 4, 0), |
| 498 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 12, 4, 0), | 500 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_COPTRC_SHIFT, 4, 0), |
| 499 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 8, 4, 0), | 501 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_MMAPDBG_SHIFT, 4, 0), |
| 500 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 4, 4, 0), | 502 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_COPSDBG_SHIFT, 4, 0), |
| 501 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, 0, 4, 0), | 503 | ARM64_FTR_BITS(FTR_HIDDEN, FTR_STRICT, FTR_LOWER_SAFE, ID_DFR0_COPDBG_SHIFT, 4, 0), |
| 502 | ARM64_FTR_END, | 504 | ARM64_FTR_END, |
| 503 | }; | 505 | }; |
| 504 | 506 | ||
| @@ -697,11 +699,52 @@ static s64 arm64_ftr_safe_value(const struct arm64_ftr_bits *ftrp, s64 new, · 192 unmodified lines | |||
| 697 | 699 | ||
| 698 | static void __init sort_ftr_regs(void) | 700 | static void __init sort_ftr_regs(void) |
| 699 | { | 701 | { |
| 700 | int i; | 702 | unsigned int i; |
| 703 | |||
| 704 | for (i = 0; i < ARRAY_SIZE(arm64_ftr_regs); i++) { | ||
| 705 | const struct arm64_ftr_reg *ftr_reg = arm64_ftr_regs[i].reg; | ||
| 706 | const struct arm64_ftr_bits *ftr_bits = ftr_reg->ftr_bits; | ||
| 707 | unsigned int j = 0; | ||
| 708 | |||
| 709 | /* | ||
| 710 | * Features here must be sorted in descending order with respect | ||
| 711 | * to their shift values and should not overlap with each other. | ||
| 712 | */ | ||
| 713 | for (; ftr_bits->width != 0; ftr_bits++, j++) { | ||
| 714 | unsigned int width = ftr_reg->ftr_bits[j].width; | ||
| 715 | unsigned int shift = ftr_reg->ftr_bits[j].shift; | ||
| 716 | unsigned int prev_shift; | ||
| 717 | |||
| 718 | WARN((shift + width) > 64, | ||
| 719 | "%s has invalid feature at shift %d\n", | ||
| 720 | ftr_reg->name, shift); | ||
| 721 | |||
| 722 | /* | ||
| 723 | * Skip the first feature. There is nothing to | ||
| 724 | * compare against for now. | ||
| 725 | */ | ||
| 726 | if (j == 0) | ||
| 727 | continue; | ||
| 728 | |||
| 729 | prev_shift = ftr_reg->ftr_bits[j - 1].shift; | ||
| 730 | WARN((shift + width) > prev_shift, | ||
| 731 | "%s has feature overlap at shift %d\n", | ||
| 732 | ftr_reg->name, shift); | ||
| 733 | } | ||
| 701 | 734 | ||
| 702 | /* Check that the array is sorted so that we can do the binary search */ | 735 | /* |
| 703 | for (i = 1; i < ARRAY_SIZE(arm64_ftr_regs); i++) | 736 | * Skip the first register. There is nothing to |
| 737 | * compare against for now. | ||
| 738 | */ | ||
| 739 | if (i == 0) | ||
| 740 | continue; | ||
| 741 | /* | ||
| 742 | * Registers here must be sorted in ascending order with respect | ||
| 743 | * to sys_id for subsequent binary search in get_arm64_ftr_reg() | ||
| 744 | * to work correctly. | ||
| 745 | */ | ||
| 704 | BUG_ON(arm64_ftr_regs[i].sys_id < arm64_ftr_regs[i - 1].sys_id); | 746 | BUG_ON(arm64_ftr_regs[i].sys_id < arm64_ftr_regs[i - 1].sys_id); |
| 747 | } | ||
| 705 | } | 748 | } |
| 706 | 749 | ||
| 707 | /* | 750 | /* |
| @@ -1884,6 +1927,26 @@ static const struct arm64_cpu_capabilities arm64_features[] = { · 1176 unmodified lines | |||
| 1884 | .matches = has_cpuid_feature, | 1927 | .matches = has_cpuid_feature, |
| 1885 | .cpu_enable = cpu_has_fwb, | 1928 | .cpu_enable = cpu_has_fwb, |
| 1886 | }, | 1929 | }, |
| 1930 | { | ||
| 1931 | .desc = "ARMv8.4 Translation Table Level", | ||
| 1932 | .type = ARM64_CPUCAP_SYSTEM_FEATURE, | ||
| 1933 | .capability = ARM64_HAS_ARMv8_4_TTL, | ||
| 1934 | .sys_reg = SYS_ID_AA64MMFR2_EL1, | ||
| 1935 | .sign = FTR_UNSIGNED, | ||
| 1936 | .field_pos = ID_AA64MMFR2_TTL_SHIFT, | ||
| 1937 | .min_field_value = 1, | ||
| 1938 | .matches = has_cpuid_feature, | ||
| 1939 | }, | ||
| 1940 | { | ||
| 1941 | .desc = "TLB range maintenance instructions", | ||
| 1942 | .capability = ARM64_HAS_TLB_RANGE, | ||
| 1943 | .type = ARM64_CPUCAP_SYSTEM_FEATURE, | ||
| 1944 | .matches = has_cpuid_feature, | ||
| 1945 | .sys_reg = SYS_ID_AA64ISAR0_EL1, | ||
| 1946 | .field_pos = ID_AA64ISAR0_TLB_SHIFT, | ||
| 1947 | .sign = FTR_UNSIGNED, | ||
| 1948 | .min_field_value = ID_AA64ISAR0_TLB_RANGE, | ||
| 1949 | }, | ||
| 1887 | #ifdef CONFIG_ARM64_HW_AFDBM | 1950 | #ifdef CONFIG_ARM64_HW_AFDBM |
| 1888 | { | 1951 | { |
| 1889 | /* | 1952 | /* |
| @@ -93,6 +93,7 @@ static const char *const hwcap_str[] = { · 92 unmodified lines | |||
| 93 | "dgh", | 93 | "dgh", |
| 94 | "rng", | 94 | "rng", |
| 95 | "bti", | 95 | "bti", |
| 96 | /* reserved for "mte" */ | ||
| 96 | NULL | 97 | NULL |
| 97 | }; | 98 | }; |
| 98 | 99 | ||
| @@ -7,6 +7,14 @@ · 6 unmodified lines | |||
| 7 | #include <linux/crash_core.h> | 7 | #include <linux/crash_core.h> |
| 8 | #include <asm/cpufeature.h> | 8 | #include <asm/cpufeature.h> |
| 9 | #include <asm/memory.h> | 9 | #include <asm/memory.h> |
| 10 | #include <asm/pgtable-hwdef.h> | ||
| 11 | |||
| 12 | static inline u64 get_tcr_el1_t1sz(void); | ||
| 13 | |||
| 14 | static inline u64 get_tcr_el1_t1sz(void) | ||
| 15 | { | ||
| 16 | return (read_sysreg(tcr_el1) & TCR_T1SZ_MASK) >> TCR_T1SZ_OFFSET; | ||
| 17 | } | ||
| 10 | 18 | ||
| 11 | void arch_crash_save_vmcoreinfo(void) | 19 | void arch_crash_save_vmcoreinfo(void) |
| 12 | { | 20 | { |
| @@ -16,6 +24,8 @@ void arch_crash_save_vmcoreinfo(void) · 3 unmodified lines | |||
| 16 | kimage_voffset); | 24 | kimage_voffset); |
| 17 | vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n", | 25 | vmcoreinfo_append_str("NUMBER(PHYS_OFFSET)=0x%llx\n", |
| 18 | PHYS_OFFSET); | 26 | PHYS_OFFSET); |
| 27 | vmcoreinfo_append_str("NUMBER(TCR_EL1_T1SZ)=0x%llx\n", | ||
| 28 | get_tcr_el1_t1sz()); | ||
| 19 | vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); | 29 | vmcoreinfo_append_str("KERNELOFFSET=%lx\n", kaslr_offset()); |
| 20 | vmcoreinfo_append_str("NUMBER(KERNELPACMASK)=0x%llx\n", | 30 | vmcoreinfo_append_str("NUMBER(KERNELPACMASK)=0x%llx\n", |
| 21 | system_supports_address_auth() ? | 31 | system_supports_address_auth() ? |
| @@ -15,6 +15,7 @@ · 14 unmodified lines | |||
| 15 | #include <asm/assembler.h> | 15 | #include <asm/assembler.h> |
| 16 | #include <asm/asm-offsets.h> | 16 | #include <asm/asm-offsets.h> |
| 17 | #include <asm/asm_pointer_auth.h> | 17 | #include <asm/asm_pointer_auth.h> |
| 18 | #include <asm/bug.h> | ||
| 18 | #include <asm/cpufeature.h> | 19 | #include <asm/cpufeature.h> |
| 19 | #include <asm/errno.h> | 20 | #include <asm/errno.h> |
| 20 | #include <asm/esr.h> | 21 | #include <asm/esr.h> |
| @@ -226,28 +227,9 @@ alternative_else_nop_endif · 205 unmodified lines | |||
| 226 | add x29, sp, #S_STACKFRAME | 227 | add x29, sp, #S_STACKFRAME |
| 227 | 228 | ||
| 228 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN | 229 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN |
| 229 | /* | 230 | alternative_if_not ARM64_HAS_PAN |
| 230 | * Set the TTBR0 PAN bit in SPSR. When the exception is taken from | 231 | bl __swpan_entry_el\el |
| 231 | * EL0, there is no need to check the state of TTBR0_EL1 since | ||
| 232 | * accesses are always enabled. | ||
| 233 | * Note that the meaning of this bit differs from the ARMv8.1 PAN | ||
| 234 | * feature as all TTBR0_EL1 accesses are disabled, not just those to | ||
| 235 | * user mappings. | ||
| 236 | */ | ||
| 237 | alternative_if ARM64_HAS_PAN | ||
| 238 | b 1f // skip TTBR0 PAN | ||
| 239 | alternative_else_nop_endif | 232 | alternative_else_nop_endif |
| 240 | |||
| 241 | .if \el != 0 | ||
| 242 | mrs x21, ttbr0_el1 | ||
| 243 | tst x21, #TTBR_ASID_MASK // Check for the reserved ASID | ||
| 244 | orr x23, x23, #PSR_PAN_BIT // Set the emulated PAN in the saved SPSR | ||
| 245 | b.eq 1f // TTBR0 access already disabled | ||
| 246 | and x23, x23, #~PSR_PAN_BIT // Clear the emulated PAN in the saved SPSR | ||
| 247 | .endif | ||
| 248 | |||
| 249 | __uaccess_ttbr0_disable x21 | ||
| 250 | 1: | ||
| 251 | #endif | 233 | #endif |
| 252 | 234 | ||
| 253 | stp x22, x23, [sp, #S_PC] | 235 | stp x22, x23, [sp, #S_PC] |
| @@ -301,34 +283,9 @@ alternative_else_nop_endif · 47 unmodified lines | |||
| 301 | .endif | 283 | .endif |
| 302 | 284 | ||
| 303 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN | 285 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN |
| 304 | /* | 286 | alternative_if_not ARM64_HAS_PAN |
| 305 | * Restore access to TTBR0_EL1. If returning to EL0, no need for SPSR | 287 | bl __swpan_exit_el\el |
| 306 | * PAN bit checking. | ||
| 307 | */ | ||
| 308 | alternative_if ARM64_HAS_PAN | ||
| 309 | b 2f // skip TTBR0 PAN | ||
| 310 | alternative_else_nop_endif | 288 | alternative_else_nop_endif |
| 311 | |||
| 312 | .if \el != 0 | ||
| 313 | tbnz x22, #22, 1f // Skip re-enabling TTBR0 access if the PSR_PAN_BIT is set | ||
| 314 | .endif | ||
| 315 | |||
| 316 | __uaccess_ttbr0_enable x0, x1 | ||
| 317 | |||
| 318 | .if \el == 0 | ||
| 319 | /* | ||
| 320 | * Enable errata workarounds only if returning to user. The only | ||
| 321 | * workaround currently required for TTBR0_EL1 changes are for the | ||
| 322 | * Cavium erratum 27456 (broadcast TLBI instructions may cause I-cache | ||
| 323 | * corruption). | ||
| 324 | */ | ||
| 325 | bl post_ttbr_update_workaround | ||
| 326 | .endif | ||
| 327 | 1: | ||
| 328 | .if \el != 0 | ||
| 329 | and x22, x22, #~PSR_PAN_BIT // ARMv8.0 CPUs do not understand this bit | ||
| 330 | .endif | ||
| 331 | 2: | ||
| 332 | #endif | 289 | #endif |
| 333 | 290 | ||
| 334 | .if \el == 0 | 291 | .if \el == 0 |
| @@ -401,6 +358,49 @@ alternative_insn eret, nop, ARM64_UNMAP_KERNEL_AT_EL0 · 66 unmodified lines | |||
| 401 | sb | 358 | sb |
| 402 | .endm | 359 | .endm |
| 403 | 360 | ||
| 361 | #ifdef CONFIG_ARM64_SW_TTBR0_PAN | ||
| 362 | /* | ||
| 363 | * Set the TTBR0 PAN bit in SPSR. When the exception is taken from | ||
| 364 | * EL0, there is no need to check the state of TTBR0_EL1 since | ||
| 365 | * accesses are always enabled. | ||
| 366 | * Note that the meaning of this bit differs from the ARMv8.1 PAN | ||
| 367 | * feature as all TTBR0_EL1 accesses are disabled, not just those to | ||
| 368 | * user mappings. | ||
| 369 | */ | ||
| 370 | SYM_CODE_START_LOCAL(__swpan_entry_el1) | ||
| 371 | mrs x21, ttbr0_el1 | ||
| 372 | tst x21, #TTBR_ASID_MASK // Check for the reserved ASID | ||
| 373 | orr x23, x23, #PSR_PAN_BIT // Set the emulated PAN in the saved SPSR | ||
| 374 | b.eq 1f // TTBR0 access already disabled | ||
| 375 | and x23, x23, #~PSR_PAN_BIT // Clear the emulated PAN in the saved SPSR | ||
| 376 | SYM_INNER_LABEL(__swpan_entry_el0, SYM_L_LOCAL) | ||
| 377 | __uaccess_ttbr0_disable x21 | ||
| 378 | 1: ret | ||
| 379 | SYM_CODE_END(__swpan_entry_el1) | ||
| 380 | |||
| 381 | /* | ||
| 382 | * Restore access to TTBR0_EL1. If returning to EL0, no need for SPSR | ||
| 383 | * PAN bit checking. | ||
| 384 | */ | ||
| 385 | SYM_CODE_START_LOCAL(__swpan_exit_el1) | ||
| 386 | tbnz x22, #22, 1f // Skip re-enabling TTBR0 access if the PSR_PAN_BIT is set | ||
| 387 | __uaccess_ttbr0_enable x0, x1 | ||
| 388 | 1: and x22, x22, #~PSR_PAN_BIT // ARMv8.0 CPUs do not understand this bit | ||
| 389 | ret | ||
| 390 | SYM_CODE_END(__swpan_exit_el1) | ||
| 391 | |||
| 392 | SYM_CODE_START_LOCAL(__swpan_exit_el0) | ||
| 393 | __uaccess_ttbr0_enable x0, x1 | ||
| 394 | /* | ||
| 395 | * Enable errata workarounds only if returning to user. The only | ||
| 396 | * workaround currently required for TTBR0_EL1 changes are for the | ||
| 397 | * Cavium erratum 27456 (broadcast TLBI instructions may cause I-cache | ||
| 398 | * corruption). | ||
| 399 | */ | ||
| 400 | b post_ttbr_update_workaround | ||
| 401 | SYM_CODE_END(__swpan_exit_el0) | ||
| 402 | #endif | ||
| 403 | |||
| 404 | .macro irq_stack_entry | 404 | .macro irq_stack_entry |
| 405 | mov x19, sp // preserve the original sp | 405 | mov x19, sp // preserve the original sp |
| 406 | #ifdef CONFIG_SHADOW_CALL_STACK | 406 | #ifdef CONFIG_SHADOW_CALL_STACK |
| @@ -253,6 +253,40 @@ static unsigned int count_plts(Elf64_Sym *syms, Elf64_Rela *rela, int num, · 252 unmodified lines | |||
| 253 | return ret; | 253 | return ret; |
| 254 | } | 254 | } |
| 255 | 255 | ||
| 256 | static bool branch_rela_needs_plt(Elf64_Sym *syms, Elf64_Rela *rela, | ||
| 257 | Elf64_Word dstidx) | ||
| 258 | { | ||
| 259 | |||
| 260 | Elf64_Sym *s = syms + ELF64_R_SYM(rela->r_info); | ||
| 261 | |||
| 262 | if (s->st_shndx == dstidx) | ||
| 263 | return false; | ||
| 264 | |||
| 265 | return ELF64_R_TYPE(rela->r_info) == R_AARCH64_JUMP26 || | ||
| 266 | ELF64_R_TYPE(rela->r_info) == R_AARCH64_CALL26; | ||
| 267 | } | ||
| 268 | |||
| 269 | /* Group branch PLT relas at the front end of the array. */ | ||
| 270 | static int partition_branch_plt_relas(Elf64_Sym *syms, Elf64_Rela *rela, | ||
| 271 | int numrels, Elf64_Word dstidx) | ||
| 272 | { | ||
| 273 | int i = 0, j = numrels - 1; | ||
| 274 | |||
| 275 | if (!IS_ENABLED(CONFIG_RANDOMIZE_BASE)) | ||
| 276 | return 0; | ||
| 277 | |||
| 278 | while (i < j) { | ||
| 279 | if (branch_rela_needs_plt(syms, &rela[i], dstidx)) | ||
| 280 | i++; | ||
| 281 | else if (branch_rela_needs_plt(syms, &rela[j], dstidx)) | ||
| 282 | swap(rela[i], rela[j]); | ||
| 283 | else | ||
| 284 | j--; | ||
| 285 | } | ||
| 286 | |||
| 287 | return i; | ||
| 288 | } | ||
| 289 | |||
| 256 | int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, | 290 | int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, |
| 257 | char *secstrings, struct module *mod) | 291 | char *secstrings, struct module *mod) |
| 258 | { | 292 | { |
| @@ -290,7 +324,7 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, · 31 unmodified lines | |||
| 290 | 324 | ||
| 291 | for (i = 0; i < ehdr->e_shnum; i++) { | 325 | for (i = 0; i < ehdr->e_shnum; i++) { |
| 292 | Elf64_Rela *rels = (void *)ehdr + sechdrs[i].sh_offset; | 326 | Elf64_Rela *rels = (void *)ehdr + sechdrs[i].sh_offset; |
| 293 | int numrels = sechdrs[i].sh_size / sizeof(Elf64_Rela); | 327 | int nents, numrels = sechdrs[i].sh_size / sizeof(Elf64_Rela); |
| 294 | Elf64_Shdr *dstsec = sechdrs + sechdrs[i].sh_info; | 328 | Elf64_Shdr *dstsec = sechdrs + sechdrs[i].sh_info; |
| 295 | 329 | ||
| 296 | if (sechdrs[i].sh_type != SHT_RELA) | 330 | if (sechdrs[i].sh_type != SHT_RELA) |
| @@ -300,8 +334,14 @@ int module_frob_arch_sections(Elf_Ehdr *ehdr, Elf_Shdr *sechdrs, · 3 unmodified lines | |||
| 300 | if (!(dstsec->sh_flags & SHF_EXECINSTR)) | 334 | if (!(dstsec->sh_flags & SHF_EXECINSTR)) |
| 301 | continue; | 335 | continue; |
| 302 | 336 | ||
| 303 | /* sort by type, symbol index and addend */ | 337 | /* |
| 304 | sort(rels, numrels, sizeof(Elf64_Rela), cmp_rela, NULL); | 338 | * sort branch relocations requiring a PLT by type, symbol index |
| 339 | * and addend | ||
| 340 | */ | ||
| 341 | nents = partition_branch_plt_relas(syms, rels, numrels, | ||
| 342 | sechdrs[i].sh_info); | ||
| 343 | if (nents) | ||
| 344 | sort(rels, nents, sizeof(Elf64_Rela), cmp_rela, NULL); | ||
| 305 | 345 | ||
| 306 | if (!str_has_prefix(secstrings + dstsec->sh_name, ".init")) | 346 | if (!str_has_prefix(secstrings + dstsec->sh_name, ".init")) |
| 307 | core_plts += count_plts(syms, rels, numrels, | 347 | core_plts += count_plts(syms, rels, numrels, |
| @@ -13,12 +13,15 @@ · 12 unmodified lines | |||
| 13 | #include <asm/sysreg.h> | 13 | #include <asm/sysreg.h> |
| 14 | #include <asm/virt.h> | 14 | #include <asm/virt.h> |
| 15 | 15 | ||
| 16 | #include <clocksource/arm_arch_timer.h> | ||
| 17 | |||
| 16 | #include <linux/acpi.h> | 18 | #include <linux/acpi.h> |
| 17 | #include <linux/clocksource.h> | 19 | #include <linux/clocksource.h> |
| 18 | #include <linux/kvm_host.h> | 20 | #include <linux/kvm_host.h> |
| 19 | #include <linux/of.h> | 21 | #include <linux/of.h> |
| 20 | #include <linux/perf/arm_pmu.h> | 22 | #include <linux/perf/arm_pmu.h> |
| 21 | #include <linux/platform_device.h> | 23 | #include <linux/platform_device.h> |
| 24 | #include <linux/sched_clock.h> | ||
| 22 | #include <linux/smp.h> | 25 | #include <linux/smp.h> |
| 23 | 26 | ||
| 24 | /* ARMv8 Cortex-A53 specific event types. */ | 27 | /* ARMv8 Cortex-A53 specific event types. */ |
| @@ -155,7 +158,7 @@ armv8pmu_events_sysfs_show(struct device *dev, · 130 unmodified lines | |||
| 155 | 158 | ||
| 156 | pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr); | 159 | pmu_attr = container_of(attr, struct perf_pmu_events_attr, attr); |
| 157 | 160 | ||
| 158 | return sprintf(page, "event=0x%03llx\n", pmu_attr->id); | 161 | return sprintf(page, "event=0x%04llx\n", pmu_attr->id); |
| 159 | } | 162 | } |
| 160 | 163 | ||
| 161 | #define ARMV8_EVENT_ATTR(name, config) \ | 164 | #define ARMV8_EVENT_ATTR(name, config) \ |
| @@ -222,10 +225,29 @@ static struct attribute *armv8_pmuv3_event_attrs[] = { · 60 unmodified lines | |||
| 222 | ARMV8_EVENT_ATTR(ll_cache_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_RD), | 225 | ARMV8_EVENT_ATTR(ll_cache_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_RD), |
| 223 | ARMV8_EVENT_ATTR(ll_cache_miss_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD), | 226 | ARMV8_EVENT_ATTR(ll_cache_miss_rd, ARMV8_PMUV3_PERFCTR_LL_CACHE_MISS_RD), |
| 224 | ARMV8_EVENT_ATTR(remote_access_rd, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD), | 227 | ARMV8_EVENT_ATTR(remote_access_rd, ARMV8_PMUV3_PERFCTR_REMOTE_ACCESS_RD), |
| 228 | ARMV8_EVENT_ATTR(l1d_cache_lmiss_rd, ARMV8_PMUV3_PERFCTR_L1D_CACHE_LMISS_RD), | ||
| 229 | ARMV8_EVENT_ATTR(op_retired, ARMV8_PMUV3_PERFCTR_OP_RETIRED), | ||
| 230 | ARMV8_EVENT_ATTR(op_spec, ARMV8_PMUV3_PERFCTR_OP_SPEC), | ||
| 231 | ARMV8_EVENT_ATTR(stall, ARMV8_PMUV3_PERFCTR_STALL), | ||
| 232 | ARMV8_EVENT_ATTR(stall_slot_backend, ARMV8_PMUV3_PERFCTR_STALL_SLOT_BACKEND), | ||
| 233 | ARMV8_EVENT_ATTR(stall_slot_frontend, ARMV8_PMUV3_PERFCTR_STALL_SLOT_FRONTEND), | ||
| 234 | ARMV8_EVENT_ATTR(stall_slot, ARMV8_PMUV3_PERFCTR_STALL_SLOT), | ||
| 225 | ARMV8_EVENT_ATTR(sample_pop, ARMV8_SPE_PERFCTR_SAMPLE_POP), | 235 | ARMV8_EVENT_ATTR(sample_pop, ARMV8_SPE_PERFCTR_SAMPLE_POP), |
| 226 | ARMV8_EVENT_ATTR(sample_feed, ARMV8_SPE_PERFCTR_SAMPLE_FEED), | 236 | ARMV8_EVENT_ATTR(sample_feed, ARMV8_SPE_PERFCTR_SAMPLE_FEED), |
| 227 | ARMV8_EVENT_ATTR(sample_filtrate, ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE), | 237 | ARMV8_EVENT_ATTR(sample_filtrate, ARMV8_SPE_PERFCTR_SAMPLE_FILTRATE), |
| 228 | ARMV8_EVENT_ATTR(sample_collision, ARMV8_SPE_PERFCTR_SAMPLE_COLLISION), | 238 | ARMV8_EVENT_ATTR(sample_collision, ARMV8_SPE_PERFCTR_SAMPLE_COLLISION), |
| 239 | ARMV8_EVENT_ATTR(cnt_cycles, ARMV8_AMU_PERFCTR_CNT_CYCLES), | ||
| 240 | ARMV8_EVENT_ATTR(stall_backend_mem, ARMV8_AMU_PERFCTR_STALL_BACKEND_MEM), | ||
| 241 | ARMV8_EVENT_ATTR(l1i_cache_lmiss, ARMV8_PMUV3_PERFCTR_L1I_CACHE_LMISS), | ||
| 242 | ARMV8_EVENT_ATTR(l2d_cache_lmiss_rd, ARMV8_PMUV3_PERFCTR_L2D_CACHE_LMISS_RD), | ||
| 243 | ARMV8_EVENT_ATTR(l2i_cache_lmiss, ARMV8_PMUV3_PERFCTR_L2I_CACHE_LMISS), | ||
| 244 | ARMV8_EVENT_ATTR(l3d_cache_lmiss_rd, ARMV8_PMUV3_PERFCTR_L3D_CACHE_LMISS_RD), | ||
| 245 | ARMV8_EVENT_ATTR(ldst_align_lat, ARMV8_PMUV3_PERFCTR_LDST_ALIGN_LAT), | ||
| 246 | ARMV8_EVENT_ATTR(ld_align_lat, ARMV8_PMUV3_PERFCTR_LD_ALIGN_LAT), | ||
| 247 | ARMV8_EVENT_ATTR(st_align_lat, ARMV8_PMUV3_PERFCTR_ST_ALIGN_LAT), | ||
| 248 | ARMV8_EVENT_ATTR(mem_access_checked, ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED), | ||
| 249 | ARMV8_EVENT_ATTR(mem_access_checked_rd, ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED_RD), | ||
| 250 | ARMV8_EVENT_ATTR(mem_access_checked_wr, ARMV8_MTE_PERFCTR_MEM_ACCESS_CHECKED_WR), | ||
| 229 | NULL, | 251 | NULL, |
| 230 | }; | 252 | }; |
| 231 | 253 | ||
| @@ -244,10 +266,13 @@ armv8pmu_event_attr_is_visible(struct kobject *kobj, · 12 unmodified lines | |||
| 244 | test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap)) | 266 | test_bit(pmu_attr->id, cpu_pmu->pmceid_bitmap)) |
| 245 | return attr->mode; | 267 | return attr->mode; |
| 246 | 268 | ||
| 247 | pmu_attr->id -= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; | 269 | if (pmu_attr->id >= ARMV8_PMUV3_EXT_COMMON_EVENT_BASE) { |
| 248 | if (pmu_attr->id < ARMV8_PMUV3_MAX_COMMON_EVENTS && | 270 | u64 id = pmu_attr->id - ARMV8_PMUV3_EXT_COMMON_EVENT_BASE; |
| 249 | test_bit(pmu_attr->id, cpu_pmu->pmceid_ext_bitmap)) | 271 | |
| 250 | return attr->mode; | 272 | if (id < ARMV8_PMUV3_MAX_COMMON_EVENTS && |
| 273 | test_bit(id, cpu_pmu->pmceid_ext_bitmap)) | ||
| 274 | return attr->mode; | ||
| 275 | } | ||
| 251 | 276 | ||
| 252 | return 0; | 277 | return 0; |
| 253 | } | 278 | } |
| @@ -1165,28 +1190,54 @@ device_initcall(armv8_pmu_driver_init) · 911 unmodified lines | |||
| 1165 | void arch_perf_update_userpage(struct perf_event *event, | 1190 | void arch_perf_update_userpage(struct perf_event *event, |
| 1166 | struct perf_event_mmap_page *userpg, u64 now) | 1191 | struct perf_event_mmap_page *userpg, u64 now) |
| 1167 | { | 1192 | { |
| 1168 | u32 freq; | 1193 | struct clock_read_data *rd; |
| 1169 | u32 shift; | 1194 | unsigned int seq; |
| 1195 | u64 ns; | ||
| 1170 | 1196 | ||
| 1171 | /* | 1197 | userpg->cap_user_time = 0; |
| 1172 | * Internal timekeeping for enabled/running/stopped times | 1198 | userpg->cap_user_time_zero = 0; |
| 1173 | * is always computed with the sched_clock. | 1199 | userpg->cap_user_time_short = 0; |
| 1174 | */ | 1200 | |
| 1175 | freq = arch_timer_get_rate(); | 1201 | do { |
| 1176 | userpg->cap_user_time = 1; | 1202 | rd = sched_clock_read_begin(&seq); |
| 1203 | |||
| 1204 | if (rd->read_sched_clock != arch_timer_read_counter) | ||
| 1205 | return; | ||
| 1206 | |||
| 1207 | userpg->time_mult = rd->mult; | ||
| 1208 | userpg->time_shift = rd->shift; | ||
| 1209 | userpg->time_zero = rd->epoch_ns; | ||
| 1210 | userpg->time_cycles = rd->epoch_cyc; | ||
| 1211 | userpg->time_mask = rd->sched_clock_mask; | ||
| 1212 | |||
| 1213 | /* | ||
| 1214 | * Subtract the cycle base, such that software that | ||
| 1215 | * doesn't know about cap_user_time_short still 'works' | ||
| 1216 | * assuming no wraps. | ||
| 1217 | */ | ||
| 1218 | ns = mul_u64_u32_shr(rd->epoch_cyc, rd->mult, rd->shift); | ||
| 1219 | userpg->time_zero -= ns; | ||
| 1220 | |||
| 1221 | } while (sched_clock_read_retry(seq)); | ||
| 1222 | |||
| 1223 | userpg->time_offset = userpg->time_zero - now; | ||
| 1177 | 1224 | ||
| 1178 | clocks_calc_mult_shift(&userpg->time_mult, &shift, freq, | ||
| 1179 | NSEC_PER_SEC, 0); | ||
| 1180 | /* | 1225 | /* |
| 1181 | * time_shift is not expected to be greater than 31 due to | 1226 | * time_shift is not expected to be greater than 31 due to |
| 1182 | * the original published conversion algorithm shifting a | 1227 | * the original published conversion algorithm shifting a |
| 1183 | * 32-bit value (now specifies a 64-bit value) - refer | 1228 | * 32-bit value (now specifies a 64-bit value) - refer |
| 1184 | * perf_event_mmap_page documentation in perf_event.h. | 1229 | * perf_event_mmap_page documentation in perf_event.h. |
| 1185 | */ | 1230 | */ |
| 1186 | if (shift == 32) { | 1231 | if (userpg->time_shift == 32) { |
| 1187 | shift = 31; | 1232 | userpg->time_shift = 31; |
| 1188 | userpg->time_mult >>= 1; | 1233 | userpg->time_mult >>= 1; |
| 1189 | } | 1234 | } |
| 1190 | userpg->time_shift = (u16)shift; | 1235 | |
| 1191 | userpg->time_offset = -now; | 1236 | /* |
| 1237 | * Internal timekeeping for enabled/running/stopped times | ||
| 1238 | * is always computed with the sched_clock. | ||
| 1239 | */ | ||
| 1240 | userpg->cap_user_time = 1; | ||
| 1241 | userpg->cap_user_time_zero = 1; | ||
| 1242 | userpg->cap_user_time_short = 1; | ||
| 1192 | } | 1243 | } |
| @@ -400,11 +400,7 @@ static int __init topology_init(void) · 399 unmodified lines | |||
| 400 | } | 400 | } |
| 401 | subsys_initcall(topology_init); | 401 | subsys_initcall(topology_init); |
| 402 | 402 | ||
| 403 | /* | 403 | static void dump_kernel_offset(void) |
| 404 | * Dump out kernel offset information on panic. | ||
| 405 | */ | ||
| 406 | static int dump_kernel_offset(struct notifier_block *self, unsigned long v, | ||
| 407 | void *p) | ||
| 408 | { | 404 | { |
| 409 | const unsigned long offset = kaslr_offset(); | 405 | const unsigned long offset = kaslr_offset(); |
| 410 | 406 | ||
| @@ -415,17 +411,25 @@ static int dump_kernel_offset(struct notifier_block *self, unsigned long v, · 4 unmodified lines | |||
| 415 | } else { | 411 | } else { |
| 416 | pr_emerg("Kernel Offset: disabled\n"); | 412 | pr_emerg("Kernel Offset: disabled\n"); |
| 417 | } | 413 | } |
| 414 | } | ||
| 415 | |||
| 416 | static int arm64_panic_block_dump(struct notifier_block *self, | ||
| 417 | unsigned long v, void *p) | ||
| 418 | { | ||
| 419 | dump_kernel_offset(); | ||
| 420 | dump_cpu_features(); | ||
| 421 | dump_mem_limit(); | ||
| 418 | return 0; | 422 | return 0; |
| 419 | } | 423 | } |
| 420 | 424 | ||
| 421 | static struct notifier_block kernel_offset_notifier = { | 425 | static struct notifier_block arm64_panic_block = { |
| 422 | .notifier_call = dump_kernel_offset | 426 | .notifier_call = arm64_panic_block_dump |
| 423 | }; | 427 | }; |
| 424 | 428 | ||
| 425 | static int __init register_kernel_offset_dumper(void) | 429 | static int __init register_arm64_panic_block(void) |
| 426 | { | 430 | { |
| 427 | atomic_notifier_chain_register(&panic_notifier_list, | 431 | atomic_notifier_chain_register(&panic_notifier_list, |
| 428 | &kernel_offset_notifier); | 432 | &arm64_panic_block); |
| 429 | return 0; | 433 | return 0; |
| 430 | } | 434 | } |
| 431 | __initcall(register_kernel_offset_dumper); | 435 | device_initcall(register_arm64_panic_block); |
| @@ -199,12 +199,12 @@ static noinline void __save_stack_trace(struct task_struct *tsk, · 198 unmodified lines | |||
| 199 | 199 | ||
| 200 | put_task_stack(tsk); | 200 | put_task_stack(tsk); |
| 201 | } | 201 | } |
| 202 | EXPORT_SYMBOL_GPL(save_stack_trace_tsk); | ||
| 203 | 202 | ||
| 204 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) | 203 | void save_stack_trace_tsk(struct task_struct *tsk, struct stack_trace *trace) |
| 205 | { | 204 | { |
| 206 | __save_stack_trace(tsk, trace, 1); | 205 | __save_stack_trace(tsk, trace, 1); |
| 207 | } | 206 | } |
| 207 | EXPORT_SYMBOL_GPL(save_stack_trace_tsk); | ||
| 208 | 208 | ||
| 209 | void save_stack_trace(struct stack_trace *trace) | 209 | void save_stack_trace(struct stack_trace *trace) |
| 210 | { | 210 | { |
| @@ -855,7 +855,7 @@ asmlinkage void handle_bad_stack(struct pt_regs *regs) · 854 unmodified lines | |||
| 855 | pr_emerg("Task stack: [0x%016lx..0x%016lx]\n", | 855 | pr_emerg("Task stack: [0x%016lx..0x%016lx]\n", |
| 856 | tsk_stk, tsk_stk + THREAD_SIZE); | 856 | tsk_stk, tsk_stk + THREAD_SIZE); |
| 857 | pr_emerg("IRQ stack: [0x%016lx..0x%016lx]\n", | 857 | pr_emerg("IRQ stack: [0x%016lx..0x%016lx]\n", |
| 858 | irq_stk, irq_stk + THREAD_SIZE); | 858 | irq_stk, irq_stk + IRQ_STACK_SIZE); |
| 859 | pr_emerg("Overflow stack: [0x%016lx..0x%016lx]\n", | 859 | pr_emerg("Overflow stack: [0x%016lx..0x%016lx]\n", |
| 860 | ovf_stk, ovf_stk + OVERFLOW_STACK_SIZE); | 860 | ovf_stk, ovf_stk + OVERFLOW_STACK_SIZE); |
| 861 | 861 | ||
| @@ -18,6 +18,7 @@ · 17 unmodified lines | |||
| 18 | #include <linux/sched.h> | 18 | #include <linux/sched.h> |
| 19 | #include <linux/signal.h> | 19 | #include <linux/signal.h> |
| 20 | #include <linux/slab.h> | 20 | #include <linux/slab.h> |
| 21 | #include <linux/time_namespace.h> | ||
| 21 | #include <linux/timekeeper_internal.h> | 22 | #include <linux/timekeeper_internal.h> |
| 22 | #include <linux/vmalloc.h> | 23 | #include <linux/vmalloc.h> |
| 23 | #include <vdso/datapage.h> | 24 | #include <vdso/datapage.h> |
| @@ -40,6 +41,12 @@ enum vdso_abi { · 16 unmodified lines | |||
| 40 | #endif /* CONFIG_COMPAT_VDSO */ | 41 | #endif /* CONFIG_COMPAT_VDSO */ |
| 41 | }; | 42 | }; |
| 42 | 43 | ||
| 44 | enum vvar_pages { | ||
| 45 | VVAR_DATA_PAGE_OFFSET, | ||
| 46 | VVAR_TIMENS_PAGE_OFFSET, | ||
| 47 | VVAR_NR_PAGES, | ||
| 48 | }; | ||
| 49 | |||
| 43 | struct vdso_abi_info { | 50 | struct vdso_abi_info { |
| 44 | const char *name; | 51 | const char *name; |
| 45 | const char *vdso_code_start; | 52 | const char *vdso_code_start; |
| @@ -107,25 +114,122 @@ static int __vdso_init(enum vdso_abi abi) · 61 unmodified lines | |||
| 107 | vdso_info[abi].vdso_code_start) >> | 114 | vdso_info[abi].vdso_code_start) >> |
| 108 | PAGE_SHIFT; | 115 | PAGE_SHIFT; |
| 109 | 116 | ||
| 110 | /* Allocate the vDSO pagelist, plus a page for the data. */ | 117 | vdso_pagelist = kcalloc(vdso_info[abi].vdso_pages, |
| 111 | vdso_pagelist = kcalloc(vdso_info[abi].vdso_pages + 1, | ||
| 112 | sizeof(struct page *), | 118 | sizeof(struct page *), |
| 113 | GFP_KERNEL); | 119 | GFP_KERNEL); |
| 114 | if (vdso_pagelist == NULL) | 120 | if (vdso_pagelist == NULL) |
| 115 | return -ENOMEM; | 121 | return -ENOMEM; |
| 116 | 122 | ||
| 117 | /* Grab the vDSO data page. */ | ||
| 118 | vdso_pagelist[0] = phys_to_page(__pa_symbol(vdso_data)); | ||
| 119 | |||
| 120 | |||
| 121 | /* Grab the vDSO code pages. */ | 123 | /* Grab the vDSO code pages. */ |
| 122 | pfn = sym_to_pfn(vdso_info[abi].vdso_code_start); | 124 | pfn = sym_to_pfn(vdso_info[abi].vdso_code_start); |
| 123 | 125 | ||
| 124 | for (i = 0; i < vdso_info[abi].vdso_pages; i++) | 126 | for (i = 0; i < vdso_info[abi].vdso_pages; i++) |
| 125 | vdso_pagelist[i + 1] = pfn_to_page(pfn + i); | 127 | vdso_pagelist[i] = pfn_to_page(pfn + i); |
| 128 | |||
| 129 | vdso_info[abi].cm->pages = vdso_pagelist; | ||
| 130 | |||
| 131 | return 0; | ||
| 132 | } | ||
| 133 | |||
| 134 | #ifdef CONFIG_TIME_NS | ||
| 135 | struct vdso_data *arch_get_vdso_data(void *vvar_page) | ||
| 136 | { | ||
| 137 | return (struct vdso_data *)(vvar_page); | ||
| 138 | } | ||
| 139 | |||
| 140 | /* | ||
| 141 | * The vvar mapping contains data for a specific time namespace, so when a task | ||
| 142 | * changes namespace we must unmap its vvar data for the old namespace. | ||
| 143 | * Subsequent faults will map in data for the new namespace. | ||
| 144 | * | ||
| 145 | * For more details see timens_setup_vdso_data(). | ||
| 146 | */ | ||
| 147 | int vdso_join_timens(struct task_struct *task, struct time_namespace *ns) | ||
| 148 | { | ||
| 149 | struct mm_struct *mm = task->mm; | ||
| 150 | struct vm_area_struct *vma; | ||
| 151 | |||
| 152 | mmap_read_lock(mm); | ||
| 153 | |||
| 154 | for (vma = mm->mmap; vma; vma = vma->vm_next) { | ||
| 155 | unsigned long size = vma->vm_end - vma->vm_start; | ||
| 126 | 156 | ||
| 127 | vdso_info[abi].dm->pages = &vdso_pagelist[0]; | 157 | if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA64].dm)) |
| 128 | vdso_info[abi].cm->pages = &vdso_pagelist[1]; | 158 | zap_page_range(vma, vma->vm_start, size); |
| 159 | #ifdef CONFIG_COMPAT_VDSO | ||
| 160 | if (vma_is_special_mapping(vma, vdso_info[VDSO_ABI_AA32].dm)) | ||
| 161 | zap_page_range(vma, vma->vm_start, size); | ||
| 162 | #endif | ||
| 163 | } | ||
| 164 | |||
| 165 | mmap_read_unlock(mm); | ||
| 166 | return 0; | ||
| 167 | } | ||
| 168 | |||
| 169 | static struct page *find_timens_vvar_page(struct vm_area_struct *vma) | ||
| 170 | { | ||
| 171 | if (likely(vma->vm_mm == current->mm)) | ||
| 172 | return current->nsproxy->time_ns->vvar_page; | ||
| 173 | |||
| 174 | /* | ||
| 175 | * VM_PFNMAP | VM_IO protect .fault() handler from being called | ||
| 176 | * through interfaces like /proc/$pid/mem or | ||
| 177 | * process_vm_{readv,writev}() as long as there's no .access() | ||
| 178 | * in special_mapping_vmops. | ||
| 179 | * For more details check_vma_flags() and __access_remote_vm() | ||
| 180 | */ | ||
| 181 | WARN(1, "vvar_page accessed remotely"); | ||
| 182 | |||
| 183 | return NULL; | ||
| 184 | } | ||
| 185 | #else | ||
| 186 | static struct page *find_timens_vvar_page(struct vm_area_struct *vma) | ||
| 187 | { | ||
| 188 | return NULL; | ||
| 189 | } | ||
| 190 | #endif | ||
| 191 | |||
| 192 | static vm_fault_t vvar_fault(const struct vm_special_mapping *sm, | ||
| 193 | struct vm_area_struct *vma, struct vm_fault *vmf) | ||
| 194 | { | ||
| 195 | struct page *timens_page = find_timens_vvar_page(vma); | ||
| 196 | unsigned long pfn; | ||
| 197 | |||
| 198 | switch (vmf->pgoff) { | ||
| 199 | case VVAR_DATA_PAGE_OFFSET: | ||
| 200 | if (timens_page) | ||
| 201 | pfn = page_to_pfn(timens_page); | ||
| 202 | else | ||
| 203 | pfn = sym_to_pfn(vdso_data); | ||
| 204 | break; | ||
| 205 | #ifdef CONFIG_TIME_NS | ||
| 206 | case VVAR_TIMENS_PAGE_OFFSET: | ||
| 207 | /* | ||
| 208 | * If a task belongs to a time namespace then a namespace | ||
| 209 | * specific VVAR is mapped with the VVAR_DATA_PAGE_OFFSET and | ||
| 210 | * the real VVAR page is mapped with the VVAR_TIMENS_PAGE_OFFSET | ||
| 211 | * offset. | ||
| 212 | * See also the comment near timens_setup_vdso_data(). | ||
| 213 | */ | ||
| 214 | if (!timens_page) | ||
| 215 | return VM_FAULT_SIGBUS; | ||
| 216 | pfn = sym_to_pfn(vdso_data); | ||
| 217 | break; | ||
| 218 | #endif /* CONFIG_TIME_NS */ | ||
| 219 | default: | ||
| 220 | return VM_FAULT_SIGBUS; | ||
| 221 | } | ||
| 222 | |||
| 223 | return vmf_insert_pfn(vma, vmf->address, pfn); | ||
| 224 | } | ||
| 225 | |||
| 226 | static int vvar_mremap(const struct vm_special_mapping *sm, | ||
| 227 | struct vm_area_struct *new_vma) | ||
| 228 | { | ||
| 229 | unsigned long new_size = new_vma->vm_end - new_vma->vm_start; | ||
| 230 | |||
| 231 | if (new_size != VVAR_NR_PAGES * PAGE_SIZE) | ||
| 232 | return -EINVAL; | ||
| 129 | 233 | ||
| 130 | return 0; | 234 | return 0; |
| 131 | } | 235 | } |
| @@ -139,9 +243,11 @@ static int __setup_additional_pages(enum vdso_abi abi, · 7 unmodified lines | |||
| 139 | unsigned long gp_flags = 0; | 243 | unsigned long gp_flags = 0; |
| 140 | void *ret; | 244 | void *ret; |
| 141 | 245 | ||
| 246 | BUILD_BUG_ON(VVAR_NR_PAGES != __VVAR_PAGES); | ||
| 247 | |||
| 142 | vdso_text_len = vdso_info[abi].vdso_pages << PAGE_SHIFT; | 248 | vdso_text_len = vdso_info[abi].vdso_pages << PAGE_SHIFT; |
| 143 | /* Be sure to map the data page */ | 249 | /* Be sure to map the data page */ |
| 144 | vdso_mapping_len = vdso_text_len + PAGE_SIZE; | 250 | vdso_mapping_len = vdso_text_len + VVAR_NR_PAGES * PAGE_SIZE; |
| 145 | 251 | ||
| 146 | vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); | 252 | vdso_base = get_unmapped_area(NULL, 0, vdso_mapping_len, 0, 0); |
| 147 | if (IS_ERR_VALUE(vdso_base)) { | 253 | if (IS_ERR_VALUE(vdso_base)) { |
| @@ -149,8 +255,8 @@ static int __setup_additional_pages(enum vdso_abi abi, · 1 unmodified line | |||
| 149 | goto up_fail; | 255 | goto up_fail; |
| 150 | } | 256 | } |
| 151 | 257 | ||
| 152 | ret = _install_special_mapping(mm, vdso_base, PAGE_SIZE, | 258 | ret = _install_special_mapping(mm, vdso_base, VVAR_NR_PAGES * PAGE_SIZE, |
| 153 | VM_READ|VM_MAYREAD, | 259 | VM_READ|VM_MAYREAD|VM_PFNMAP, |
| 154 | vdso_info[abi].dm); | 260 | vdso_info[abi].dm); |
| 155 | if (IS_ERR(ret)) | 261 | if (IS_ERR(ret)) |
| 156 | goto up_fail; | 262 | goto up_fail; |
| @@ -158,7 +264,7 @@ static int __setup_additional_pages(enum vdso_abi abi, · 1 unmodified line | |||
| 158 | if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && system_supports_bti()) | 264 | if (IS_ENABLED(CONFIG_ARM64_BTI_KERNEL) && system_supports_bti()) |
| 159 | gp_flags = VM_ARM64_BTI; | 265 | gp_flags = VM_ARM64_BTI; |
| 160 | 266 | ||
| 161 | vdso_base += PAGE_SIZE; | 267 | vdso_base += VVAR_NR_PAGES * PAGE_SIZE; |
| 162 | mm->context.vdso = (void *)vdso_base; | 268 | mm->context.vdso = (void *)vdso_base; |
| 163 | ret = _install_special_mapping(mm, vdso_base, vdso_text_len, | 269 | ret = _install_special_mapping(mm, vdso_base, vdso_text_len, |
| 164 | VM_READ|VM_EXEC|gp_flags| | 270 | VM_READ|VM_EXEC|gp_flags| |
| @@ -206,6 +312,8 @@ static struct vm_special_mapping aarch32_vdso_maps[] = { · 41 unmodified lines | |||
| 206 | #ifdef CONFIG_COMPAT_VDSO | 312 | #ifdef CONFIG_COMPAT_VDSO |
| 207 | [AA32_MAP_VVAR] = { | 313 | [AA32_MAP_VVAR] = { |
| 208 | .name = "[vvar]", | 314 | .name = "[vvar]", |
| 315 | .fault = vvar_fault, | ||
| 316 | .mremap = vvar_mremap, | ||
| 209 | }, | 317 | }, |
| 210 | [AA32_MAP_VDSO] = { | 318 | [AA32_MAP_VDSO] = { |
| 211 | .name = "[vdso]", | 319 | .name = "[vdso]", |
| @@ -371,6 +479,8 @@ enum aarch64_map { · 159 unmodified lines | |||
| 371 | static struct vm_special_mapping aarch64_vdso_maps[] __ro_after_init = { | 479 | static struct vm_special_mapping aarch64_vdso_maps[] __ro_after_init = { |
| 372 | [AA64_MAP_VVAR] = { | 480 | [AA64_MAP_VVAR] = { |
| 373 | .name = "[vvar]", | 481 | .name = "[vvar]", |
| 482 | .fault = vvar_fault, | ||
| 483 | .mremap = vvar_mremap, | ||
| 374 | }, | 484 | }, |
| 375 | [AA64_MAP_VDSO] = { | 485 | [AA64_MAP_VDSO] = { |
| 376 | .name = "[vdso]", | 486 | .name = "[vdso]", |
| @@ -17,7 +17,10 @@ OUTPUT_ARCH(aarch64) · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | SECTIONS | 18 | SECTIONS |
| 19 | { | 19 | { |
| 20 | PROVIDE(_vdso_data = . - PAGE_SIZE); | 20 | PROVIDE(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE); |
| 21 | #ifdef CONFIG_TIME_NS | ||
| 22 | PROVIDE(_timens_data = _vdso_data + PAGE_SIZE); | ||
| 23 | #endif | ||
| 21 | . = VDSO_LBASE + SIZEOF_HEADERS; | 24 | . = VDSO_LBASE + SIZEOF_HEADERS; |
| 22 | 25 | ||
| 23 | .hash : { *(.hash) } :text | 26 | .hash : { *(.hash) } :text |
| @@ -17,7 +17,10 @@ OUTPUT_ARCH(arm) · 16 unmodified lines | |||
| 17 | 17 | ||
| 18 | SECTIONS | 18 | SECTIONS |
| 19 | { | 19 | { |
| 20 | PROVIDE_HIDDEN(_vdso_data = . - PAGE_SIZE); | 20 | PROVIDE_HIDDEN(_vdso_data = . - __VVAR_PAGES * PAGE_SIZE); |
| 21 | #ifdef CONFIG_TIME_NS | ||
| 22 | PROVIDE_HIDDEN(_timens_data = _vdso_data + PAGE_SIZE); | ||
| 23 | #endif | ||
| 21 | . = VDSO_LBASE + SIZEOF_HEADERS; | 24 | . = VDSO_LBASE + SIZEOF_HEADERS; |
| 22 | 25 | ||
| 23 | .hash : { *(.hash) } :text | 26 | .hash : { *(.hash) } :text |
| @@ -10,7 +10,6 @@ · 9 unmodified lines | |||
| 10 | #include <asm-generic/vmlinux.lds.h> | 10 | #include <asm-generic/vmlinux.lds.h> |
| 11 | #include <asm/cache.h> | 11 | #include <asm/cache.h> |
| 12 | #include <asm/kernel-pgtable.h> | 12 | #include <asm/kernel-pgtable.h> |
| 13 | #include <asm/thread_info.h> | ||
| 14 | #include <asm/memory.h> | 13 | #include <asm/memory.h> |
| 15 | #include <asm/page.h> | 14 | #include <asm/page.h> |
| 16 | 15 | ||
| @@ -6,6 +6,7 @@ · 5 unmodified lines | |||
| 6 | 6 | ||
| 7 | #include <linux/linkage.h> | 7 | #include <linux/linkage.h> |
| 8 | 8 | ||
| 9 | #include <asm/alternative.h> | ||
| 9 | #include <asm/assembler.h> | 10 | #include <asm/assembler.h> |
| 10 | #include <asm/kvm_arm.h> | 11 | #include <asm/kvm_arm.h> |
| 11 | #include <asm/kvm_mmu.h> | 12 | #include <asm/kvm_mmu.h> |
| @@ -1024,9 +1024,9 @@ static bool access_amu(struct kvm_vcpu *vcpu, struct sys_reg_params *p, · 1023 unmodified lines | |||
| 1024 | 1024 | ||
| 1025 | /* Macro to expand the AMU counter and type registers*/ | 1025 | /* Macro to expand the AMU counter and type registers*/ |
| 1026 | #define AMU_AMEVCNTR0_EL0(n) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), access_amu } | 1026 | #define AMU_AMEVCNTR0_EL0(n) { SYS_DESC(SYS_AMEVCNTR0_EL0(n)), access_amu } |
| 1027 | #define AMU_AMEVTYPE0_EL0(n) { SYS_DESC(SYS_AMEVTYPE0_EL0(n)), access_amu } | 1027 | #define AMU_AMEVTYPER0_EL0(n) { SYS_DESC(SYS_AMEVTYPER0_EL0(n)), access_amu } |
| 1028 | #define AMU_AMEVCNTR1_EL0(n) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), access_amu } | 1028 | #define AMU_AMEVCNTR1_EL0(n) { SYS_DESC(SYS_AMEVCNTR1_EL0(n)), access_amu } |
| 1029 | #define AMU_AMEVTYPE1_EL0(n) { SYS_DESC(SYS_AMEVTYPE1_EL0(n)), access_amu } | 1029 | #define AMU_AMEVTYPER1_EL0(n) { SYS_DESC(SYS_AMEVTYPER1_EL0(n)), access_amu } |
| 1030 | 1030 | ||
| 1031 | static bool trap_ptrauth(struct kvm_vcpu *vcpu, | 1031 | static bool trap_ptrauth(struct kvm_vcpu *vcpu, |
| 1032 | struct sys_reg_params *p, | 1032 | struct sys_reg_params *p, |
| @@ -1629,22 +1629,22 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 596 unmodified lines | |||
| 1629 | AMU_AMEVCNTR0_EL0(13), | 1629 | AMU_AMEVCNTR0_EL0(13), |
| 1630 | AMU_AMEVCNTR0_EL0(14), | 1630 | AMU_AMEVCNTR0_EL0(14), |
| 1631 | AMU_AMEVCNTR0_EL0(15), | 1631 | AMU_AMEVCNTR0_EL0(15), |
| 1632 | AMU_AMEVTYPE0_EL0(0), | 1632 | AMU_AMEVTYPER0_EL0(0), |
| 1633 | AMU_AMEVTYPE0_EL0(1), | 1633 | AMU_AMEVTYPER0_EL0(1), |
| 1634 | AMU_AMEVTYPE0_EL0(2), | 1634 | AMU_AMEVTYPER0_EL0(2), |
| 1635 | AMU_AMEVTYPE0_EL0(3), | 1635 | AMU_AMEVTYPER0_EL0(3), |
| 1636 | AMU_AMEVTYPE0_EL0(4), | 1636 | AMU_AMEVTYPER0_EL0(4), |
| 1637 | AMU_AMEVTYPE0_EL0(5), | 1637 | AMU_AMEVTYPER0_EL0(5), |
| 1638 | AMU_AMEVTYPE0_EL0(6), | 1638 | AMU_AMEVTYPER0_EL0(6), |
| 1639 | AMU_AMEVTYPE0_EL0(7), | 1639 | AMU_AMEVTYPER0_EL0(7), |
| 1640 | AMU_AMEVTYPE0_EL0(8), | 1640 | AMU_AMEVTYPER0_EL0(8), |
| 1641 | AMU_AMEVTYPE0_EL0(9), | 1641 | AMU_AMEVTYPER0_EL0(9), |
| 1642 | AMU_AMEVTYPE0_EL0(10), | 1642 | AMU_AMEVTYPER0_EL0(10), |
| 1643 | AMU_AMEVTYPE0_EL0(11), | 1643 | AMU_AMEVTYPER0_EL0(11), |
| 1644 | AMU_AMEVTYPE0_EL0(12), | 1644 | AMU_AMEVTYPER0_EL0(12), |
| 1645 | AMU_AMEVTYPE0_EL0(13), | 1645 | AMU_AMEVTYPER0_EL0(13), |
| 1646 | AMU_AMEVTYPE0_EL0(14), | 1646 | AMU_AMEVTYPER0_EL0(14), |
| 1647 | AMU_AMEVTYPE0_EL0(15), | 1647 | AMU_AMEVTYPER0_EL0(15), |
| 1648 | AMU_AMEVCNTR1_EL0(0), | 1648 | AMU_AMEVCNTR1_EL0(0), |
| 1649 | AMU_AMEVCNTR1_EL0(1), | 1649 | AMU_AMEVCNTR1_EL0(1), |
| 1650 | AMU_AMEVCNTR1_EL0(2), | 1650 | AMU_AMEVCNTR1_EL0(2), |
| @@ -1661,22 +1661,22 @@ static const struct sys_reg_desc sys_reg_descs[] = { · 10 unmodified lines | |||
| 1661 | AMU_AMEVCNTR1_EL0(13), | 1661 | AMU_AMEVCNTR1_EL0(13), |
| 1662 | AMU_AMEVCNTR1_EL0(14), | 1662 | AMU_AMEVCNTR1_EL0(14), |
| 1663 | AMU_AMEVCNTR1_EL0(15), | 1663 | AMU_AMEVCNTR1_EL0(15), |
| 1664 | AMU_AMEVTYPE1_EL0(0), | 1664 | AMU_AMEVTYPER1_EL0(0), |
| 1665 | AMU_AMEVTYPE1_EL0(1), | 1665 | AMU_AMEVTYPER1_EL0(1), |
| 1666 | AMU_AMEVTYPE1_EL0(2), | 1666 | AMU_AMEVTYPER1_EL0(2), |
| 1667 | AMU_AMEVTYPE1_EL0(3), | 1667 | AMU_AMEVTYPER1_EL0(3), |
| 1668 | AMU_AMEVTYPE1_EL0(4), | 1668 | AMU_AMEVTYPER1_EL0(4), |
| 1669 | AMU_AMEVTYPE1_EL0(5), | 1669 | AMU_AMEVTYPER1_EL0(5), |
| 1670 | AMU_AMEVTYPE1_EL0(6), | 1670 | AMU_AMEVTYPER1_EL0(6), |
| 1671 | AMU_AMEVTYPE1_EL0(7), | 1671 | AMU_AMEVTYPER1_EL0(7), |
| 1672 | AMU_AMEVTYPE1_EL0(8), | 1672 | AMU_AMEVTYPER1_EL0(8), |
| 1673 | AMU_AMEVTYPE1_EL0(9), | 1673 | AMU_AMEVTYPER1_EL0(9), |
| 1674 | AMU_AMEVTYPE1_EL0(10), | 1674 | AMU_AMEVTYPER1_EL0(10), |
| 1675 | AMU_AMEVTYPE1_EL0(11), | 1675 | AMU_AMEVTYPER1_EL0(11), |
| 1676 | AMU_AMEVTYPE1_EL0(12), | 1676 | AMU_AMEVTYPER1_EL0(12), |
| 1677 | AMU_AMEVTYPE1_EL0(13), | 1677 | AMU_AMEVTYPER1_EL0(13), |
| 1678 | AMU_AMEVTYPE1_EL0(14), | 1678 | AMU_AMEVTYPER1_EL0(14), |
| 1679 | AMU_AMEVTYPE1_EL0(15), | 1679 | AMU_AMEVTYPER1_EL0(15), |
| 1680 | 1680 | ||
| 1681 | { SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer }, | 1681 | { SYS_DESC(SYS_CNTP_TVAL_EL0), access_arch_timer }, |
| 1682 | { SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer }, | 1682 | { SYS_DESC(SYS_CNTP_CTL_EL0), access_arch_timer }, |
| @@ -198,9 +198,10 @@ set_asid: · 197 unmodified lines | |||
| 198 | return idx2asid(asid) | generation; | 198 | return idx2asid(asid) | generation; |
| 199 | } | 199 | } |
| 200 | 200 | ||
| 201 | void check_and_switch_context(struct mm_struct *mm, unsigned int cpu) | 201 | void check_and_switch_context(struct mm_struct *mm) |
| 202 | { | 202 | { |
| 203 | unsigned long flags; | 203 | unsigned long flags; |
| 204 | unsigned int cpu; | ||
| 204 | u64 asid, old_active_asid; | 205 | u64 asid, old_active_asid; |
| 205 | 206 | ||
| 206 | if (system_supports_cnp()) | 207 | if (system_supports_cnp()) |
| @@ -222,9 +223,9 @@ void check_and_switch_context(struct mm_struct *mm, unsigned int cpu) · 15 unmodified lines | |||
| 222 | * relaxed xchg in flush_context will treat us as reserved | 223 | * relaxed xchg in flush_context will treat us as reserved |
| 223 | * because atomic RmWs are totally ordered for a given location. | 224 | * because atomic RmWs are totally ordered for a given location. |
| 224 | */ | 225 | */ |
| 225 | old_active_asid = atomic64_read(&per_cpu(active_asids, cpu)); | 226 | old_active_asid = atomic64_read(this_cpu_ptr(&active_asids)); |
| 226 | if (old_active_asid && asid_gen_match(asid) && | 227 | if (old_active_asid && asid_gen_match(asid) && |
| 227 | atomic64_cmpxchg_relaxed(&per_cpu(active_asids, cpu), | 228 | atomic64_cmpxchg_relaxed(this_cpu_ptr(&active_asids), |
| 228 | old_active_asid, asid)) | 229 | old_active_asid, asid)) |
| 229 | goto switch_mm_fastpath; | 230 | goto switch_mm_fastpath; |
| 230 | 231 | ||
| @@ -236,10 +237,11 @@ void check_and_switch_context(struct mm_struct *mm, unsigned int cpu) · 5 unmodified lines | |||
| 236 | atomic64_set(&mm->context.id, asid); | 237 | atomic64_set(&mm->context.id, asid); |
| 237 | } | 238 | } |
| 238 | 239 | ||
| 240 | cpu = smp_processor_id(); | ||
| 239 | if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) | 241 | if (cpumask_test_and_clear_cpu(cpu, &tlb_flush_pending)) |
| 240 | local_flush_tlb_all(); | 242 | local_flush_tlb_all(); |
| 241 | 243 | ||
| 242 | atomic64_set(&per_cpu(active_asids, cpu), asid); | 244 | atomic64_set(this_cpu_ptr(&active_asids), asid); |
| 243 | raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); | 245 | raw_spin_unlock_irqrestore(&cpu_asid_lock, flags); |
| 244 | 246 | ||
| 245 | switch_mm_fastpath: | 247 | switch_mm_fastpath: |
| @@ -19,6 +19,44 @@ · 18 unmodified lines | |||
| 19 | #include <asm/tlbflush.h> | 19 | #include <asm/tlbflush.h> |
| 20 | #include <asm/pgalloc.h> | 20 | #include <asm/pgalloc.h> |
| 21 | 21 | ||
| 22 | /* | ||
| 23 | * HugeTLB Support Matrix | ||
| 24 | * | ||
| 25 | * --------------------------------------------------- | ||
| 26 | * | Page Size | CONT PTE | PMD | CONT PMD | PUD | | ||
| 27 | * --------------------------------------------------- | ||
| 28 | * | 4K | 64K | 2M | 32M | 1G | | ||
| 29 | * | 16K | 2M | 32M | 1G | | | ||
| 30 | * | 64K | 2M | 512M | 16G | | | ||
| 31 | * --------------------------------------------------- | ||
| 32 | */ | ||
| 33 | |||
| 34 | /* | ||
| 35 | * Reserve CMA areas for the largest supported gigantic | ||
| 36 | * huge page when requested. Any other smaller gigantic | ||
| 37 | * huge pages could still be served from those areas. | ||
| 38 | */ | ||
| 39 | #ifdef CONFIG_CMA | ||
| 40 | void __init arm64_hugetlb_cma_reserve(void) | ||
| 41 | { | ||
| 42 | int order; | ||
| 43 | |||
| 44 | #ifdef CONFIG_ARM64_4K_PAGES | ||
| 45 | order = PUD_SHIFT - PAGE_SHIFT; | ||
| 46 | #else | ||
| 47 | order = CONT_PMD_SHIFT + PMD_SHIFT - PAGE_SHIFT; | ||
| 48 | #endif | ||
| 49 | /* | ||
| 50 | * HugeTLB CMA reservation is required for gigantic | ||
| 51 | * huge pages which could not be allocated via the | ||
| 52 | * page allocator. Just warn if there is any change | ||
| 53 | * breaking this assumption. | ||
| 54 | */ | ||
| 55 | WARN_ON(order <= MAX_ORDER); | ||
| 56 | hugetlb_cma_reserve(order); | ||
| 57 | } | ||
| 58 | #endif /* CONFIG_CMA */ | ||
| 59 | |||
| 22 | #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION | 60 | #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION |
| 23 | bool arch_hugetlb_migration_supported(struct hstate *h) | 61 | bool arch_hugetlb_migration_supported(struct hstate *h) |
| 24 | { | 62 | { |
| @@ -457,9 +495,9 @@ static int __init hugetlbpage_init(void) · 432 unmodified lines | |||
| 457 | #ifdef CONFIG_ARM64_4K_PAGES | 495 | #ifdef CONFIG_ARM64_4K_PAGES |
| 458 | hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); | 496 | hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); |
| 459 | #endif | 497 | #endif |
| 460 | hugetlb_add_hstate((CONT_PMD_SHIFT + PMD_SHIFT) - PAGE_SHIFT); | 498 | hugetlb_add_hstate(CONT_PMD_SHIFT - PAGE_SHIFT); |
| 461 | hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); | 499 | hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); |
| 462 | hugetlb_add_hstate((CONT_PTE_SHIFT + PAGE_SHIFT) - PAGE_SHIFT); | 500 | hugetlb_add_hstate(CONT_PTE_SHIFT - PAGE_SHIFT); |
| 463 | 501 | ||
| 464 | return 0; | 502 | return 0; |
| 465 | } | 503 | } |
| @@ -425,8 +425,8 @@ void __init bootmem_init(void) · 424 unmodified lines | |||
| 425 | * initialize node_online_map that gets used in hugetlb_cma_reserve() | 425 | * initialize node_online_map that gets used in hugetlb_cma_reserve() |
| 426 | * while allocating required CMA size across online nodes. | 426 | * while allocating required CMA size across online nodes. |
| 427 | */ | 427 | */ |
| 428 | #ifdef CONFIG_ARM64_4K_PAGES | 428 | #if defined(CONFIG_HUGETLB_PAGE) && defined(CONFIG_CMA) |
| 429 | hugetlb_cma_reserve(PUD_SHIFT - PAGE_SHIFT); | 429 | arm64_hugetlb_cma_reserve(); |
| 430 | #endif | 430 | #endif |
| 431 | 431 | ||
| 432 | /* | 432 | /* |
| @@ -563,27 +563,11 @@ void free_initmem(void) · 130 unmodified lines | |||
| 563 | unmap_kernel_range((u64)__init_begin, (u64)(__init_end - __init_begin)); | 563 | unmap_kernel_range((u64)__init_begin, (u64)(__init_end - __init_begin)); |
| 564 | } | 564 | } |
| 565 | 565 | ||
| 566 | /* | 566 | void dump_mem_limit(void) |
| 567 | * Dump out memory limit information on panic. | ||
| 568 | */ | ||
| 569 | static int dump_mem_limit(struct notifier_block *self, unsigned long v, void *p) | ||
| 570 | { | 567 | { |
| 571 | if (memory_limit != PHYS_ADDR_MAX) { | 568 | if (memory_limit != PHYS_ADDR_MAX) { |
| 572 | pr_emerg("Memory Limit: %llu MB\n", memory_limit >> 20); | 569 | pr_emerg("Memory Limit: %llu MB\n", memory_limit >> 20); |
| 573 | } else { | 570 | } else { |
| 574 | pr_emerg("Memory Limit: none\n"); | 571 | pr_emerg("Memory Limit: none\n"); |
| 575 | } | 572 | } |
| 576 | return 0; | ||
| 577 | } | ||
| 578 | |||
| 579 | static struct notifier_block mem_limit_notifier = { | ||
| 580 | .notifier_call = dump_mem_limit, | ||
| 581 | }; | ||
| 582 | |||
| 583 | static int __init register_mem_limit_dumper(void) | ||
| 584 | { | ||
| 585 | atomic_notifier_chain_register(&panic_notifier_list, | ||
| 586 | &mem_limit_notifier); | ||
| 587 | return 0; | ||
| 588 | } | 573 | } |
| 589 | __initcall(register_mem_limit_dumper); | ||
| @@ -4,6 +4,7 @@ · 3 unmodified lines | |||
| 4 | 4 | ||
| 5 | #ifndef __ASSEMBLY__ | 5 | #ifndef __ASSEMBLY__ |
| 6 | 6 | ||
| 7 | #include <asm/barrier.h> | ||
| 7 | #include <asm/unistd.h> | 8 | #include <asm/unistd.h> |
| 8 | #include <asm/csr.h> | 9 | #include <asm/csr.h> |
| 9 | #include <uapi/linux/time.h> | 10 | #include <uapi/linux/time.h> |
| @@ -264,15 +264,31 @@ static acpi_status iort_match_node_callback(struct acpi_iort_node *node, · 263 unmodified lines | |||
| 264 | 264 | ||
| 265 | if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) { | 265 | if (node->type == ACPI_IORT_NODE_NAMED_COMPONENT) { |
| 266 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; | 266 | struct acpi_buffer buf = { ACPI_ALLOCATE_BUFFER, NULL }; |
| 267 | struct acpi_device *adev = to_acpi_device_node(dev->fwnode); | 267 | struct acpi_device *adev; |
| 268 | struct acpi_iort_named_component *ncomp; | 268 | struct acpi_iort_named_component *ncomp; |
| 269 | struct device *nc_dev = dev; | ||
| 270 | |||
| 271 | /* | ||
| 272 | * Walk the device tree to find a device with an | ||
| 273 | * ACPI companion; there is no point in scanning | ||
| 274 | * IORT for a device matching a named component if | ||
| 275 | * the device does not have an ACPI companion to | ||
| 276 | * start with. | ||
| 277 | */ | ||
| 278 | do { | ||
| 279 | adev = ACPI_COMPANION(nc_dev); | ||
| 280 | if (adev) | ||
| 281 | break; | ||
| 282 | |||
| 283 | nc_dev = nc_dev->parent; | ||
| 284 | } while (nc_dev); | ||
| 269 | 285 | ||
| 270 | if (!adev) | 286 | if (!adev) |
| 271 | goto out; | 287 | goto out; |
| 272 | 288 | ||
| 273 | status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf); | 289 | status = acpi_get_name(adev->handle, ACPI_FULL_PATHNAME, &buf); |
| 274 | if (ACPI_FAILURE(status)) { | 290 | if (ACPI_FAILURE(status)) { |
| 275 | dev_warn(dev, "Can't get device full path name\n"); | 291 | dev_warn(nc_dev, "Can't get device full path name\n"); |
| 276 | goto out; | 292 | goto out; |
| 277 | } | 293 | } |
| 278 | 294 | ||
| @@ -534,7 +550,6 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev) · 255 unmodified lines | |||
| 534 | node = iort_get_iort_node(dev->fwnode); | 550 | node = iort_get_iort_node(dev->fwnode); |
| 535 | if (node) | 551 | if (node) |
| 536 | return node; | 552 | return node; |
| 537 | |||
| 538 | /* | 553 | /* |
| 539 | * if not, then it should be a platform device defined in | 554 | * if not, then it should be a platform device defined in |
| 540 | * DSDT/SSDT (with Named Component node in IORT) | 555 | * DSDT/SSDT (with Named Component node in IORT) |
| @@ -543,32 +558,29 @@ static struct acpi_iort_node *iort_find_dev_node(struct device *dev) · 2 unmodified lines | |||
| 543 | iort_match_node_callback, dev); | 558 | iort_match_node_callback, dev); |
| 544 | } | 559 | } |
| 545 | 560 | ||
| 546 | /* Find a PCI root bus */ | ||
| 547 | pbus = to_pci_dev(dev)->bus; | 561 | pbus = to_pci_dev(dev)->bus; |
| 548 | while (!pci_is_root_bus(pbus)) | ||
| 549 | pbus = pbus->parent; | ||
| 550 | 562 | ||
| 551 | return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, | 563 | return iort_scan_node(ACPI_IORT_NODE_PCI_ROOT_COMPLEX, |
| 552 | iort_match_node_callback, &pbus->dev); | 564 | iort_match_node_callback, &pbus->dev); |
| 553 | } | 565 | } |
| 554 | 566 | ||
| 555 | /** | 567 | /** |
| 556 | * iort_msi_map_rid() - Map a MSI requester ID for a device | 568 | * iort_msi_map_id() - Map a MSI input ID for a device |
| 557 | * @dev: The device for which the mapping is to be done. | 569 | * @dev: The device for which the mapping is to be done. |
| 558 | * @req_id: The device requester ID. | 570 | * @input_id: The device input ID. |
| 559 | * | 571 | * |
| 560 | * Returns: mapped MSI RID on success, input requester ID otherwise | 572 | * Returns: mapped MSI ID on success, input ID otherwise |
| 561 | */ | 573 | */ |
| 562 | u32 iort_msi_map_rid(struct device *dev, u32 req_id) | 574 | u32 iort_msi_map_id(struct device *dev, u32 input_id) |
| 563 | { | 575 | { |
| 564 | struct acpi_iort_node *node; | 576 | struct acpi_iort_node *node; |
| 565 | u32 dev_id; | 577 | u32 dev_id; |
| 566 | 578 | ||
| 567 | node = iort_find_dev_node(dev); | 579 | node = iort_find_dev_node(dev); |
| 568 | if (!node) | 580 | if (!node) |
| 569 | return req_id; | 581 | return input_id; |
| 570 | 582 | ||
| 571 | iort_node_map_id(node, req_id, &dev_id, IORT_MSI_TYPE); | 583 | iort_node_map_id(node, input_id, &dev_id, IORT_MSI_TYPE); |
| 572 | return dev_id; | 584 | return dev_id; |
| 573 | } | 585 | } |
| 574 | 586 | ||
| @@ -625,13 +637,13 @@ static int __maybe_unused iort_find_its_base(u32 its_id, phys_addr_t *base) · 50 unmodified lines | |||
| 625 | /** | 637 | /** |
| 626 | * iort_dev_find_its_id() - Find the ITS identifier for a device | 638 | * iort_dev_find_its_id() - Find the ITS identifier for a device |
| 627 | * @dev: The device. | 639 | * @dev: The device. |
| 628 | * @req_id: Device's requester ID | 640 | * @id: Device's ID |
| 629 | * @idx: Index of the ITS identifier list. | 641 | * @idx: Index of the ITS identifier list. |
| 630 | * @its_id: ITS identifier. | 642 | * @its_id: ITS identifier. |
| 631 | * | 643 | * |
| 632 | * Returns: 0 on success, appropriate error value otherwise | 644 | * Returns: 0 on success, appropriate error value otherwise |
| 633 | */ | 645 | */ |
| 634 | static int iort_dev_find_its_id(struct device *dev, u32 req_id, | 646 | static int iort_dev_find_its_id(struct device *dev, u32 id, |
| 635 | unsigned int idx, int *its_id) | 647 | unsigned int idx, int *its_id) |
| 636 | { | 648 | { |
| 637 | struct acpi_iort_its_group *its; | 649 | struct acpi_iort_its_group *its; |
| @@ -641,7 +653,7 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id, · 3 unmodified lines | |||
| 641 | if (!node) | 653 | if (!node) |
| 642 | return -ENXIO; | 654 | return -ENXIO; |
| 643 | 655 | ||
| 644 | node = iort_node_map_id(node, req_id, NULL, IORT_MSI_TYPE); | 656 | node = iort_node_map_id(node, id, NULL, IORT_MSI_TYPE); |
| 645 | if (!node) | 657 | if (!node) |
| 646 | return -ENXIO; | 658 | return -ENXIO; |
| 647 | 659 | ||
| @@ -664,19 +676,20 @@ static int iort_dev_find_its_id(struct device *dev, u32 req_id, · 16 unmodified lines | |||
| 664 | * | 676 | * |
| 665 | * Returns: the MSI domain for this device, NULL otherwise | 677 | * Returns: the MSI domain for this device, NULL otherwise |
| 666 | */ | 678 | */ |
| 667 | struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id) | 679 | struct irq_domain *iort_get_device_domain(struct device *dev, u32 id, |
| 680 | enum irq_domain_bus_token bus_token) | ||
| 668 | { | 681 | { |
| 669 | struct fwnode_handle *handle; | 682 | struct fwnode_handle *handle; |
| 670 | int its_id; | 683 | int its_id; |
| 671 | 684 | ||
| 672 | if (iort_dev_find_its_id(dev, req_id, 0, &its_id)) | 685 | if (iort_dev_find_its_id(dev, id, 0, &its_id)) |
| 673 | return NULL; | 686 | return NULL; |
| 674 | 687 | ||
| 675 | handle = iort_find_domain_token(its_id); | 688 | handle = iort_find_domain_token(its_id); |
| 676 | if (!handle) | 689 | if (!handle) |
| 677 | return NULL; | 690 | return NULL; |
| 678 | 691 | ||
| 679 | return irq_find_matching_fwnode(handle, DOMAIN_BUS_PCI_MSI); | 692 | return irq_find_matching_fwnode(handle, bus_token); |
| 680 | } | 693 | } |
| 681 | 694 | ||
| 682 | static void iort_set_device_domain(struct device *dev, | 695 | static void iort_set_device_domain(struct device *dev, |
| @@ -965,19 +978,54 @@ static void iort_named_component_init(struct device *dev, · 282 unmodified lines | |||
| 965 | nc->node_flags); | 978 | nc->node_flags); |
| 966 | } | 979 | } |
| 967 | 980 | ||
| 981 | static int iort_nc_iommu_map(struct device *dev, struct acpi_iort_node *node) | ||
| 982 | { | ||
| 983 | struct acpi_iort_node *parent; | ||
| 984 | int err = -ENODEV, i = 0; | ||
| 985 | u32 streamid = 0; | ||
| 986 | |||
| 987 | do { | ||
| 988 | |||
| 989 | parent = iort_node_map_platform_id(node, &streamid, | ||
| 990 | IORT_IOMMU_TYPE, | ||
| 991 | i++); | ||
| 992 | |||
| 993 | if (parent) | ||
| 994 | err = iort_iommu_xlate(dev, parent, streamid); | ||
| 995 | } while (parent && !err); | ||
| 996 | |||
| 997 | return err; | ||
| 998 | } | ||
| 999 | |||
| 1000 | static int iort_nc_iommu_map_id(struct device *dev, | ||
| 1001 | struct acpi_iort_node *node, | ||
| 1002 | const u32 *in_id) | ||
| 1003 | { | ||
| 1004 | struct acpi_iort_node *parent; | ||
| 1005 | u32 streamid; | ||
| 1006 | |||
| 1007 | parent = iort_node_map_id(node, *in_id, &streamid, IORT_IOMMU_TYPE); | ||
| 1008 | if (parent) | ||
| 1009 | return iort_iommu_xlate(dev, parent, streamid); | ||
| 1010 | |||
| 1011 | return -ENODEV; | ||
| 1012 | } | ||
| 1013 | |||
| 1014 | |||
| 968 | /** | 1015 | /** |
| 969 | * iort_iommu_configure - Set-up IOMMU configuration for a device. | 1016 | * iort_iommu_configure_id - Set-up IOMMU configuration for a device. |
| 970 | * | 1017 | * |
| 971 | * @dev: device to configure | 1018 | * @dev: device to configure |
| 1019 | * @id_in: optional input id const value pointer | ||
| 972 | * | 1020 | * |
| 973 | * Returns: iommu_ops pointer on configuration success | 1021 | * Returns: iommu_ops pointer on configuration success |
| 974 | * NULL on configuration failure | 1022 | * NULL on configuration failure |
| 975 | */ | 1023 | */ |
| 976 | const struct iommu_ops *iort_iommu_configure(struct device *dev) | 1024 | const struct iommu_ops *iort_iommu_configure_id(struct device *dev, |
| 1025 | const u32 *id_in) | ||
| 977 | { | 1026 | { |
| 978 | struct acpi_iort_node *node, *parent; | 1027 | struct acpi_iort_node *node; |
| 979 | const struct iommu_ops *ops; | 1028 | const struct iommu_ops *ops; |
| 980 | u32 streamid = 0; | ||
| 981 | int err = -ENODEV; | 1029 | int err = -ENODEV; |
| 982 | 1030 | ||
| 983 | /* | 1031 | /* |
| @@ -1006,21 +1054,13 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) · 22 unmodified lines | |||
| 1006 | if (fwspec && iort_pci_rc_supports_ats(node)) | 1054 | if (fwspec && iort_pci_rc_supports_ats(node)) |
| 1007 | fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS; | 1055 | fwspec->flags |= IOMMU_FWSPEC_PCI_RC_ATS; |
| 1008 | } else { | 1056 | } else { |
| 1009 | int i = 0; | ||
| 1010 | |||
| 1011 | node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, | 1057 | node = iort_scan_node(ACPI_IORT_NODE_NAMED_COMPONENT, |
| 1012 | iort_match_node_callback, dev); | 1058 | iort_match_node_callback, dev); |
| 1013 | if (!node) | 1059 | if (!node) |
| 1014 | return NULL; | 1060 | return NULL; |
| 1015 | 1061 | ||
| 1016 | do { | 1062 | err = id_in ? iort_nc_iommu_map_id(dev, node, id_in) : |
| 1017 | parent = iort_node_map_platform_id(node, &streamid, | 1063 | iort_nc_iommu_map(dev, node); |
| 1018 | IORT_IOMMU_TYPE, | ||
| 1019 | i++); | ||
| 1020 | |||
| 1021 | if (parent) | ||
| 1022 | err = iort_iommu_xlate(dev, parent, streamid); | ||
| 1023 | } while (parent && !err); | ||
| 1024 | 1064 | ||
| 1025 | if (!err) | 1065 | if (!err) |
| 1026 | iort_named_component_init(dev, node); | 1066 | iort_named_component_init(dev, node); |
| @@ -1045,6 +1085,7 @@ const struct iommu_ops *iort_iommu_configure(struct device *dev) · 18 unmodified lines | |||
| 1045 | 1085 | ||
| 1046 | return ops; | 1086 | return ops; |
| 1047 | } | 1087 | } |
| 1088 | |||
| 1048 | #else | 1089 | #else |
| 1049 | static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) | 1090 | static inline const struct iommu_ops *iort_fwspec_iommu_ops(struct device *dev) |
| 1050 | { return NULL; } | 1091 | { return NULL; } |
| @@ -1053,7 +1094,8 @@ static inline int iort_add_device_replay(const struct iommu_ops *ops, · 2 unmodified lines | |||
| 1053 | { return 0; } | 1094 | { return 0; } |
| 1054 | int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) | 1095 | int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) |
| 1055 | { return 0; } | 1096 | { return 0; } |
| 1056 | const struct iommu_ops *iort_iommu_configure(struct device *dev) | 1097 | const struct iommu_ops *iort_iommu_configure_id(struct device *dev, |
| 1098 | const u32 *input_id) | ||
| 1057 | { return NULL; } | 1099 | { return NULL; } |
| 1058 | #endif | 1100 | #endif |
| 1059 | 1101 | ||
| @@ -1457,8 +1457,10 @@ int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset, · 1456 unmodified lines | |||
| 1457 | * acpi_dma_configure - Set-up DMA configuration for the device. | 1457 | * acpi_dma_configure - Set-up DMA configuration for the device. |
| 1458 | * @dev: The pointer to the device | 1458 | * @dev: The pointer to the device |
| 1459 | * @attr: device dma attributes | 1459 | * @attr: device dma attributes |
| 1460 | * @input_id: input device id const value pointer | ||
| 1460 | */ | 1461 | */ |
| 1461 | int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr) | 1462 | int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr, |
| 1463 | const u32 *input_id) | ||
| 1462 | { | 1464 | { |
| 1463 | const struct iommu_ops *iommu; | 1465 | const struct iommu_ops *iommu; |
| 1464 | u64 dma_addr = 0, size = 0; | 1466 | u64 dma_addr = 0, size = 0; |
| @@ -1470,7 +1472,7 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr) · 5 unmodified lines | |||
| 1470 | 1472 | ||
| 1471 | iort_dma_setup(dev, &dma_addr, &size); | 1473 | iort_dma_setup(dev, &dma_addr, &size); |
| 1472 | 1474 | ||
| 1473 | iommu = iort_iommu_configure(dev); | 1475 | iommu = iort_iommu_configure_id(dev, input_id); |
| 1474 | if (PTR_ERR(iommu) == -EPROBE_DEFER) | 1476 | if (PTR_ERR(iommu) == -EPROBE_DEFER) |
| 1475 | return -EPROBE_DEFER; | 1477 | return -EPROBE_DEFER; |
| 1476 | 1478 | ||
| @@ -1479,7 +1481,7 @@ int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr) · 2 unmodified lines | |||
| 1479 | 1481 | ||
| 1480 | return 0; | 1482 | return 0; |
| 1481 | } | 1483 | } |
| 1482 | EXPORT_SYMBOL_GPL(acpi_dma_configure); | 1484 | EXPORT_SYMBOL_GPL(acpi_dma_configure_id); |
| 1483 | 1485 | ||
| 1484 | static void acpi_init_coherency(struct acpi_device *adev) | 1486 | static void acpi_init_coherency(struct acpi_device *adev) |
| 1485 | { | 1487 | { |
| @@ -592,6 +592,7 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) · 591 unmodified lines | |||
| 592 | bool mc_io_created = false; | 592 | bool mc_io_created = false; |
| 593 | bool msi_domain_set = false; | 593 | bool msi_domain_set = false; |
| 594 | u16 major_ver, minor_ver; | 594 | u16 major_ver, minor_ver; |
| 595 | struct irq_domain *mc_msi_domain; | ||
| 595 | 596 | ||
| 596 | if (!is_fsl_mc_bus_dprc(mc_dev)) | 597 | if (!is_fsl_mc_bus_dprc(mc_dev)) |
| 597 | return -EINVAL; | 598 | return -EINVAL; |
| @@ -621,31 +622,15 @@ static int dprc_probe(struct fsl_mc_device *mc_dev) · 23 unmodified lines | |||
| 621 | return error; | 622 | return error; |
| 622 | 623 | ||
| 623 | mc_io_created = true; | 624 | mc_io_created = true; |
| 625 | } | ||
| 624 | 626 | ||
| 625 | /* | 627 | mc_msi_domain = fsl_mc_find_msi_domain(&mc_dev->dev); |
| 626 | * Inherit parent MSI domain: | 628 | if (!mc_msi_domain) { |
| 627 | */ | 629 | dev_warn(&mc_dev->dev, |
| 628 | dev_set_msi_domain(&mc_dev->dev, | 630 | "WARNING: MC bus without interrupt support\n"); |
| 629 | dev_get_msi_domain(parent_dev)); | ||
| 630 | msi_domain_set = true; | ||
| 631 | } else { | 631 | } else { |
| 632 | /* | 632 | dev_set_msi_domain(&mc_dev->dev, mc_msi_domain); |
| 633 | * This is a root DPRC | 633 | msi_domain_set = true; |
| 634 | */ | ||
| 635 | struct irq_domain *mc_msi_domain; | ||
| 636 | |||
| 637 | if (dev_is_fsl_mc(parent_dev)) | ||
| 638 | return -EINVAL; | ||
| 639 | |||
| 640 | error = fsl_mc_find_msi_domain(parent_dev, | ||
| 641 | &mc_msi_domain); | ||
| 642 | if (error < 0) { | ||
| 643 | dev_warn(&mc_dev->dev, | ||
| 644 | "WARNING: MC bus without interrupt support\n"); | ||
| 645 | } else { | ||
| 646 | dev_set_msi_domain(&mc_dev->dev, mc_msi_domain); | ||
| 647 | msi_domain_set = true; | ||
| 648 | } | ||
| 649 | } | 634 | } |
| 650 | 635 | ||
| 651 | error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, | 636 | error = dprc_open(mc_dev->mc_io, 0, mc_dev->obj_desc.id, |
| @@ -18,6 +18,8 @@ · 17 unmodified lines | |||
| 18 | #include <linux/bitops.h> | 18 | #include <linux/bitops.h> |
| 19 | #include <linux/msi.h> | 19 | #include <linux/msi.h> |
| 20 | #include <linux/dma-mapping.h> | 20 | #include <linux/dma-mapping.h> |
| 21 | #include <linux/acpi.h> | ||
| 22 | #include <linux/iommu.h> | ||
| 21 | 23 | ||
| 22 | #include "fsl-mc-private.h" | 24 | #include "fsl-mc-private.h" |
| 23 | 25 | ||
| @@ -38,6 +40,7 @@ struct fsl_mc { · 14 unmodified lines | |||
| 38 | struct fsl_mc_device *root_mc_bus_dev; | 40 | struct fsl_mc_device *root_mc_bus_dev; |
| 39 | u8 num_translation_ranges; | 41 | u8 num_translation_ranges; |
| 40 | struct fsl_mc_addr_translation_range *translation_ranges; | 42 | struct fsl_mc_addr_translation_range *translation_ranges; |
| 43 | void *fsl_mc_regs; | ||
| 41 | }; | 44 | }; |
| 42 | 45 | ||
| 43 | /** | 46 | /** |
| @@ -56,6 +59,10 @@ struct fsl_mc_addr_translation_range { · 12 unmodified lines | |||
| 56 | phys_addr_t start_phys_addr; | 59 | phys_addr_t start_phys_addr; |
| 57 | }; | 60 | }; |
| 58 | 61 | ||
| 62 | #define FSL_MC_FAPR 0x28 | ||
| 63 | #define MC_FAPR_PL BIT(18) | ||
| 64 | #define MC_FAPR_BMT BIT(17) | ||
| 65 | |||
| 59 | /** | 66 | /** |
| 60 | * fsl_mc_bus_match - device to driver matching callback | 67 | * fsl_mc_bus_match - device to driver matching callback |
| 61 | * @dev: the fsl-mc device to match against | 68 | * @dev: the fsl-mc device to match against |
| @@ -118,11 +125,16 @@ static int fsl_mc_bus_uevent(struct device *dev, struct kobj_uevent_env *env) · 56 unmodified lines | |||
| 118 | static int fsl_mc_dma_configure(struct device *dev) | 125 | static int fsl_mc_dma_configure(struct device *dev) |
| 119 | { | 126 | { |
| 120 | struct device *dma_dev = dev; | 127 | struct device *dma_dev = dev; |
| 128 | struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); | ||
| 129 | u32 input_id = mc_dev->icid; | ||
| 121 | 130 | ||
| 122 | while (dev_is_fsl_mc(dma_dev)) | 131 | while (dev_is_fsl_mc(dma_dev)) |
| 123 | dma_dev = dma_dev->parent; | 132 | dma_dev = dma_dev->parent; |
| 124 | 133 | ||
| 125 | return of_dma_configure(dev, dma_dev->of_node, 0); | 134 | if (dev_of_node(dma_dev)) |
| 135 | return of_dma_configure_id(dev, dma_dev->of_node, 0, &input_id); | ||
| 136 | |||
| 137 | return acpi_dma_configure_id(dev, DEV_DMA_COHERENT, &input_id); | ||
| 126 | } | 138 | } |
| 127 | 139 | ||
| 128 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, | 140 | static ssize_t modalias_show(struct device *dev, struct device_attribute *attr, |
| @@ -368,8 +380,8 @@ EXPORT_SYMBOL_GPL(fsl_mc_get_version); · 239 unmodified lines | |||
| 368 | /** | 380 | /** |
| 369 | * fsl_mc_get_root_dprc - function to traverse to the root dprc | 381 | * fsl_mc_get_root_dprc - function to traverse to the root dprc |
| 370 | */ | 382 | */ |
| 371 | static void fsl_mc_get_root_dprc(struct device *dev, | 383 | void fsl_mc_get_root_dprc(struct device *dev, |
| 372 | struct device **root_dprc_dev) | 384 | struct device **root_dprc_dev) |
| 373 | { | 385 | { |
| 374 | if (!dev) { | 386 | if (!dev) { |
| 375 | *root_dprc_dev = NULL; | 387 | *root_dprc_dev = NULL; |
| @@ -863,8 +875,11 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) · 487 unmodified lines | |||
| 863 | struct fsl_mc_io *mc_io = NULL; | 875 | struct fsl_mc_io *mc_io = NULL; |
| 864 | int container_id; | 876 | int container_id; |
| 865 | phys_addr_t mc_portal_phys_addr; | 877 | phys_addr_t mc_portal_phys_addr; |
| 866 | u32 mc_portal_size; | 878 | u32 mc_portal_size, mc_stream_id; |
| 867 | struct resource res; | 879 | struct resource *plat_res; |
| 880 | |||
| 881 | if (!iommu_present(&fsl_mc_bus_type)) | ||
| 882 | return -EPROBE_DEFER; | ||
| 868 | 883 | ||
| 869 | mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL); | 884 | mc = devm_kzalloc(&pdev->dev, sizeof(*mc), GFP_KERNEL); |
| 870 | if (!mc) | 885 | if (!mc) |
| @@ -872,19 +887,33 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) · 1 unmodified line | |||
| 872 | 887 | ||
| 873 | platform_set_drvdata(pdev, mc); | 888 | platform_set_drvdata(pdev, mc); |
| 874 | 889 | ||
| 890 | plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 1); | ||
| 891 | mc->fsl_mc_regs = devm_ioremap_resource(&pdev->dev, plat_res); | ||
| 892 | if (IS_ERR(mc->fsl_mc_regs)) | ||
| 893 | return PTR_ERR(mc->fsl_mc_regs); | ||
| 894 | |||
| 895 | if (IS_ENABLED(CONFIG_ACPI) && !dev_of_node(&pdev->dev)) { | ||
| 896 | mc_stream_id = readl(mc->fsl_mc_regs + FSL_MC_FAPR); | ||
| 897 | /* | ||
| 898 | * HW ORs the PL and BMT bit, places the result in bit 15 of | ||
| 899 | * the StreamID and ORs in the ICID. Calculate it accordingly. | ||
| 900 | */ | ||
| 901 | mc_stream_id = (mc_stream_id & 0xffff) | | ||
| 902 | ((mc_stream_id & (MC_FAPR_PL | MC_FAPR_BMT)) ? | ||
| 903 | 0x4000 : 0); | ||
| 904 | error = acpi_dma_configure_id(&pdev->dev, DEV_DMA_COHERENT, | ||
| 905 | &mc_stream_id); | ||
| 906 | if (error) | ||
| 907 | dev_warn(&pdev->dev, "failed to configure dma: %d.\n", | ||
| 908 | error); | ||
| 909 | } | ||
| 910 | |||
| 875 | /* | 911 | /* |
| 876 | * Get physical address of MC portal for the root DPRC: | 912 | * Get physical address of MC portal for the root DPRC: |
| 877 | */ | 913 | */ |
| 878 | error = of_address_to_resource(pdev->dev.of_node, 0, &res); | 914 | plat_res = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 879 | if (error < 0) { | 915 | mc_portal_phys_addr = plat_res->start; |
| 880 | dev_err(&pdev->dev, | 916 | mc_portal_size = resource_size(plat_res); |
| 881 | "of_address_to_resource() failed for %pOF\n", | ||
| 882 | pdev->dev.of_node); | ||
| 883 | return error; | ||
| 884 | } | ||
| 885 | |||
| 886 | mc_portal_phys_addr = res.start; | ||
| 887 | mc_portal_size = resource_size(&res); | ||
| 888 | error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr, | 917 | error = fsl_create_mc_io(&pdev->dev, mc_portal_phys_addr, |
| 889 | mc_portal_size, NULL, | 918 | mc_portal_size, NULL, |
| 890 | FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io); | 919 | FSL_MC_IO_ATOMIC_CONTEXT_PORTAL, &mc_io); |
| @@ -901,11 +930,13 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) · 10 unmodified lines | |||
| 901 | dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n", | 930 | dev_info(&pdev->dev, "MC firmware version: %u.%u.%u\n", |
| 902 | mc_version.major, mc_version.minor, mc_version.revision); | 931 | mc_version.major, mc_version.minor, mc_version.revision); |
| 903 | 932 | ||
| 904 | error = get_mc_addr_translation_ranges(&pdev->dev, | 933 | if (dev_of_node(&pdev->dev)) { |
| 905 | &mc->translation_ranges, | 934 | error = get_mc_addr_translation_ranges(&pdev->dev, |
| 906 | &mc->num_translation_ranges); | 935 | &mc->translation_ranges, |
| 907 | if (error < 0) | 936 | &mc->num_translation_ranges); |
| 908 | goto error_cleanup_mc_io; | 937 | if (error < 0) |
| 938 | goto error_cleanup_mc_io; | ||
| 939 | } | ||
| 909 | 940 | ||
| 910 | error = dprc_get_container_id(mc_io, 0, &container_id); | 941 | error = dprc_get_container_id(mc_io, 0, &container_id); |
| 911 | if (error < 0) { | 942 | if (error < 0) { |
| @@ -932,6 +963,7 @@ static int fsl_mc_bus_probe(struct platform_device *pdev) · 20 unmodified lines | |||
| 932 | goto error_cleanup_mc_io; | 963 | goto error_cleanup_mc_io; |
| 933 | 964 | ||
| 934 | mc->root_mc_bus_dev = mc_bus_dev; | 965 | mc->root_mc_bus_dev = mc_bus_dev; |
| 966 | mc_bus_dev->dev.fwnode = pdev->dev.fwnode; | ||
| 935 | return 0; | 967 | return 0; |
| 936 | 968 | ||
| 937 | error_cleanup_mc_io: | 969 | error_cleanup_mc_io: |
| @@ -965,11 +997,18 @@ static const struct of_device_id fsl_mc_bus_match_table[] = { · 27 unmodified lines | |||
| 965 | 997 | ||
| 966 | MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table); | 998 | MODULE_DEVICE_TABLE(of, fsl_mc_bus_match_table); |
| 967 | 999 | ||
| 1000 | static const struct acpi_device_id fsl_mc_bus_acpi_match_table[] = { | ||
| 1001 | {"NXP0008", 0 }, | ||
| 1002 | { } | ||
| 1003 | }; | ||
| 1004 | MODULE_DEVICE_TABLE(acpi, fsl_mc_bus_acpi_match_table); | ||
| 1005 | |||
| 968 | static struct platform_driver fsl_mc_bus_driver = { | 1006 | static struct platform_driver fsl_mc_bus_driver = { |
| 969 | .driver = { | 1007 | .driver = { |
| 970 | .name = "fsl_mc_bus", | 1008 | .name = "fsl_mc_bus", |
| 971 | .pm = NULL, | 1009 | .pm = NULL, |
| 972 | .of_match_table = fsl_mc_bus_match_table, | 1010 | .of_match_table = fsl_mc_bus_match_table, |
| 1011 | .acpi_match_table = fsl_mc_bus_acpi_match_table, | ||
| 973 | }, | 1012 | }, |
| 974 | .probe = fsl_mc_bus_probe, | 1013 | .probe = fsl_mc_bus_probe, |
| 975 | .remove = fsl_mc_bus_remove, | 1014 | .remove = fsl_mc_bus_remove, |
| @@ -13,6 +13,7 @@ · 12 unmodified lines | |||
| 13 | #include <linux/irq.h> | 13 | #include <linux/irq.h> |
| 14 | #include <linux/irqdomain.h> | 14 | #include <linux/irqdomain.h> |
| 15 | #include <linux/msi.h> | 15 | #include <linux/msi.h> |
| 16 | #include <linux/acpi_iort.h> | ||
| 16 | 17 | ||
| 17 | #include "fsl-mc-private.h" | 18 | #include "fsl-mc-private.h" |
| 18 | 19 | ||
| @@ -177,23 +178,36 @@ struct irq_domain *fsl_mc_msi_create_irq_domain(struct fwnode_handle *fwnode, · 158 unmodified lines | |||
| 177 | return domain; | 178 | return domain; |
| 178 | } | 179 | } |
| 179 | 180 | ||
| 180 | int fsl_mc_find_msi_domain(struct device *mc_platform_dev, | 181 | struct irq_domain *fsl_mc_find_msi_domain(struct device *dev) |
| 181 | struct irq_domain **mc_msi_domain) | ||
| 182 | { | 182 | { |
| 183 | struct device *root_dprc_dev; | ||
| 184 | struct device *bus_dev; | ||
| 183 | struct irq_domain *msi_domain; | 185 | struct irq_domain *msi_domain; |
| 184 | struct device_node *mc_of_node = mc_platform_dev->of_node; | 186 | struct fsl_mc_device *mc_dev = to_fsl_mc_device(dev); |
| 185 | 187 | ||
| 186 | msi_domain = of_msi_get_domain(mc_platform_dev, mc_of_node, | 188 | fsl_mc_get_root_dprc(dev, &root_dprc_dev); |
| 187 | DOMAIN_BUS_FSL_MC_MSI); | 189 | bus_dev = root_dprc_dev->parent; |
| 188 | if (!msi_domain) { | 190 | |
| 189 | pr_err("Unable to find fsl-mc MSI domain for %pOF\n", | 191 | if (bus_dev->of_node) { |
| 190 | mc_of_node); | 192 | msi_domain = of_msi_map_get_device_domain(dev, |
| 193 | mc_dev->icid, | ||
| 194 | DOMAIN_BUS_FSL_MC_MSI); | ||
| 191 | 195 | ||
| 192 | return -ENOENT; | 196 | /* |
| 197 | * if the msi-map property is missing assume that all the | ||
| 198 | * child containers inherit the domain from the parent | ||
| 199 | */ | ||
| 200 | if (!msi_domain) | ||
| 201 | |||
| 202 | msi_domain = of_msi_get_domain(bus_dev, | ||
| 203 | bus_dev->of_node, | ||
| 204 | DOMAIN_BUS_FSL_MC_MSI); | ||
| 205 | } else { | ||
| 206 | msi_domain = iort_get_device_domain(dev, mc_dev->icid, | ||
| 207 | DOMAIN_BUS_FSL_MC_MSI); | ||
| 193 | } | 208 | } |
| 194 | 209 | ||
| 195 | *mc_msi_domain = msi_domain; | 210 | return msi_domain; |
| 196 | return 0; | ||
| 197 | } | 211 | } |
| 198 | 212 | ||
| 199 | static void fsl_mc_msi_free_descs(struct device *dev) | 213 | static void fsl_mc_msi_free_descs(struct device *dev) |
| @@ -595,8 +595,7 @@ int fsl_mc_msi_domain_alloc_irqs(struct device *dev, · 594 unmodified lines | |||
| 595 | 595 | ||
| 596 | void fsl_mc_msi_domain_free_irqs(struct device *dev); | 596 | void fsl_mc_msi_domain_free_irqs(struct device *dev); |
| 597 | 597 | ||
| 598 | int fsl_mc_find_msi_domain(struct device *mc_platform_dev, | 598 | struct irq_domain *fsl_mc_find_msi_domain(struct device *dev); |
| 599 | struct irq_domain **mc_msi_domain); | ||
| 600 | 599 | ||
| 601 | int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus, | 600 | int fsl_mc_populate_irq_pool(struct fsl_mc_bus *mc_bus, |
| 602 | unsigned int irq_count); | 601 | unsigned int irq_count); |
| @@ -613,6 +612,9 @@ void fsl_destroy_mc_io(struct fsl_mc_io *mc_io); · 10 unmodified lines | |||
| 613 | 612 | ||
| 614 | bool fsl_mc_is_root_dprc(struct device *dev); | 613 | bool fsl_mc_is_root_dprc(struct device *dev); |
| 615 | 614 | ||
| 615 | void fsl_mc_get_root_dprc(struct device *dev, | ||
| 616 | struct device **root_dprc_dev); | ||
| 617 | |||
| 616 | struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc, | 618 | struct fsl_mc_device *fsl_mc_device_lookup(struct fsl_mc_obj_desc *obj_desc, |
| 617 | struct fsl_mc_device *mc_bus_dev); | 619 | struct fsl_mc_device *mc_bus_dev); |
| 618 | 620 | ||
| @@ -118,46 +118,66 @@ static int of_iommu_xlate(struct device *dev, · 117 unmodified lines | |||
| 118 | return ret; | 118 | return ret; |
| 119 | } | 119 | } |
| 120 | 120 | ||
| 121 | struct of_pci_iommu_alias_info { | 121 | static int of_iommu_configure_dev_id(struct device_node *master_np, |
| 122 | struct device *dev; | 122 | struct device *dev, |
| 123 | struct device_node *np; | 123 | const u32 *id) |
| 124 | }; | ||
| 125 | |||
| 126 | static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) | ||
| 127 | { | 124 | { |
| 128 | struct of_pci_iommu_alias_info *info = data; | ||
| 129 | struct of_phandle_args iommu_spec = { .args_count = 1 }; | 125 | struct of_phandle_args iommu_spec = { .args_count = 1 }; |
| 130 | int err; | 126 | int err; |
| 131 | 127 | ||
| 132 | err = of_map_rid(info->np, alias, "iommu-map", "iommu-map-mask", | 128 | err = of_map_id(master_np, *id, "iommu-map", |
| 133 | &iommu_spec.np, iommu_spec.args); | 129 | "iommu-map-mask", &iommu_spec.np, |
| 130 | iommu_spec.args); | ||
| 134 | if (err) | 131 | if (err) |
| 135 | return err == -ENODEV ? NO_IOMMU : err; | 132 | return err == -ENODEV ? NO_IOMMU : err; |
| 136 | 133 | ||
| 137 | err = of_iommu_xlate(info->dev, &iommu_spec); | 134 | err = of_iommu_xlate(dev, &iommu_spec); |
| 138 | of_node_put(iommu_spec.np); | 135 | of_node_put(iommu_spec.np); |
| 139 | return err; | 136 | return err; |
| 140 | } | 137 | } |
| 141 | 138 | ||
| 142 | static int of_fsl_mc_iommu_init(struct fsl_mc_device *mc_dev, | 139 | static int of_iommu_configure_dev(struct device_node *master_np, |
| 143 | struct device_node *master_np) | 140 | struct device *dev) |
| 144 | { | 141 | { |
| 145 | struct of_phandle_args iommu_spec = { .args_count = 1 }; | 142 | struct of_phandle_args iommu_spec; |
| 146 | int err; | 143 | int err = NO_IOMMU, idx = 0; |
| 147 | 144 | ||
| 148 | err = of_map_rid(master_np, mc_dev->icid, "iommu-map", | 145 | while (!of_parse_phandle_with_args(master_np, "iommus", |
| 149 | "iommu-map-mask", &iommu_spec.np, | 146 | "#iommu-cells", |
| 150 | iommu_spec.args); | 147 | idx, &iommu_spec)) { |
| 151 | if (err) | 148 | err = of_iommu_xlate(dev, &iommu_spec); |
| 152 | return err == -ENODEV ? NO_IOMMU : err; | 149 | of_node_put(iommu_spec.np); |
| 150 | idx++; | ||
| 151 | if (err) | ||
| 152 | break; | ||
| 153 | } | ||
| 153 | 154 | ||
| 154 | err = of_iommu_xlate(&mc_dev->dev, &iommu_spec); | ||
| 155 | of_node_put(iommu_spec.np); | ||
| 156 | return err; | 155 | return err; |
| 157 | } | 156 | } |
| 158 | 157 | ||
| 158 | struct of_pci_iommu_alias_info { | ||
| 159 | struct device *dev; | ||
| 160 | struct device_node *np; | ||
| 161 | }; | ||
| 162 | |||
| 163 | static int of_pci_iommu_init(struct pci_dev *pdev, u16 alias, void *data) | ||
| 164 | { | ||
| 165 | struct of_pci_iommu_alias_info *info = data; | ||
| 166 | u32 input_id = alias; | ||
| 167 | |||
| 168 | return of_iommu_configure_dev_id(info->np, info->dev, &input_id); | ||
| 169 | } | ||
| 170 | |||
| 171 | static int of_iommu_configure_device(struct device_node *master_np, | ||
| 172 | struct device *dev, const u32 *id) | ||
| 173 | { | ||
| 174 | return (id) ? of_iommu_configure_dev_id(master_np, dev, id) : | ||
| 175 | of_iommu_configure_dev(master_np, dev); | ||
| 176 | } | ||
| 177 | |||
| 159 | const struct iommu_ops *of_iommu_configure(struct device *dev, | 178 | const struct iommu_ops *of_iommu_configure(struct device *dev, |
| 160 | struct device_node *master_np) | 179 | struct device_node *master_np, |
| 180 | const u32 *id) | ||
| 161 | { | 181 | { |
| 162 | const struct iommu_ops *ops = NULL; | 182 | const struct iommu_ops *ops = NULL; |
| 163 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); | 183 | struct iommu_fwspec *fwspec = dev_iommu_fwspec_get(dev); |
| @@ -188,21 +208,8 @@ const struct iommu_ops *of_iommu_configure(struct device *dev, · 24 unmodified lines | |||
| 188 | pci_request_acs(); | 208 | pci_request_acs(); |
| 189 | err = pci_for_each_dma_alias(to_pci_dev(dev), | 209 | err = pci_for_each_dma_alias(to_pci_dev(dev), |
| 190 | of_pci_iommu_init, &info); | 210 | of_pci_iommu_init, &info); |
| 191 | } else if (dev_is_fsl_mc(dev)) { | ||
| 192 | err = of_fsl_mc_iommu_init(to_fsl_mc_device(dev), master_np); | ||
| 193 | } else { | 211 | } else { |
| 194 | struct of_phandle_args iommu_spec; | 212 | err = of_iommu_configure_device(master_np, dev, id); |
| 195 | int idx = 0; | ||
| 196 | |||
| 197 | while (!of_parse_phandle_with_args(master_np, "iommus", | ||
| 198 | "#iommu-cells", | ||
| 199 | idx, &iommu_spec)) { | ||
| 200 | err = of_iommu_xlate(dev, &iommu_spec); | ||
| 201 | of_node_put(iommu_spec.np); | ||
| 202 | idx++; | ||
| 203 | if (err) | ||
| 204 | break; | ||
| 205 | } | ||
| 206 | 213 | ||
| 207 | fwspec = dev_iommu_fwspec_get(dev); | 214 | fwspec = dev_iommu_fwspec_get(dev); |
| 208 | if (!err && fwspec) | 215 | if (!err && fwspec) |
| @@ -7,6 +7,8 @@ · 6 unmodified lines | |||
| 7 | * | 7 | * |
| 8 | */ | 8 | */ |
| 9 | 9 | ||
| 10 | #include <linux/acpi.h> | ||
| 11 | #include <linux/acpi_iort.h> | ||
| 10 | #include <linux/of_device.h> | 12 | #include <linux/of_device.h> |
| 11 | #include <linux/of_address.h> | 13 | #include <linux/of_address.h> |
| 12 | #include <linux/irq.h> | 14 | #include <linux/irq.h> |
| @@ -23,6 +25,19 @@ static struct irq_chip its_msi_irq_chip = { · 10 unmodified lines | |||
| 23 | .irq_set_affinity = msi_domain_set_affinity | 25 | .irq_set_affinity = msi_domain_set_affinity |
| 24 | }; | 26 | }; |
| 25 | 27 | ||
| 28 | static u32 fsl_mc_msi_domain_get_msi_id(struct irq_domain *domain, | ||
| 29 | struct fsl_mc_device *mc_dev) | ||
| 30 | { | ||
| 31 | struct device_node *of_node; | ||
| 32 | u32 out_id; | ||
| 33 | |||
| 34 | of_node = irq_domain_get_of_node(domain); | ||
| 35 | out_id = of_node ? of_msi_map_id(&mc_dev->dev, of_node, mc_dev->icid) : | ||
| 36 | iort_msi_map_id(&mc_dev->dev, mc_dev->icid); | ||
| 37 | |||
| 38 | return out_id; | ||
| 39 | } | ||
| 40 | |||
| 26 | static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain, | 41 | static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain, |
| 27 | struct device *dev, | 42 | struct device *dev, |
| 28 | int nvec, msi_alloc_info_t *info) | 43 | int nvec, msi_alloc_info_t *info) |
| @@ -43,7 +58,8 @@ static int its_fsl_mc_msi_prepare(struct irq_domain *msi_domain, · 14 unmodified lines | |||
| 43 | * NOTE: This device id corresponds to the IOMMU stream ID | 58 | * NOTE: This device id corresponds to the IOMMU stream ID |
| 44 | * associated with the DPRC object (ICID). | 59 | * associated with the DPRC object (ICID). |
| 45 | */ | 60 | */ |
| 46 | info->scratchpad[0].ul = mc_bus_dev->icid; | 61 | info->scratchpad[0].ul = fsl_mc_msi_domain_get_msi_id(msi_domain, |
| 62 | mc_bus_dev); | ||
| 47 | msi_info = msi_get_domain_info(msi_domain->parent); | 63 | msi_info = msi_get_domain_info(msi_domain->parent); |
| 48 | 64 | ||
| 49 | /* Allocate at least 32 MSIs, and always as a power of 2 */ | 65 | /* Allocate at least 32 MSIs, and always as a power of 2 */ |
| @@ -66,12 +82,71 @@ static const struct of_device_id its_device_id[] = { · 16 unmodified lines | |||
| 66 | {}, | 82 | {}, |
| 67 | }; | 83 | }; |
| 68 | 84 | ||
| 69 | static int __init its_fsl_mc_msi_init(void) | 85 | static void __init its_fsl_mc_msi_init_one(struct fwnode_handle *handle, |
| 86 | const char *name) | ||
| 70 | { | 87 | { |
| 71 | struct device_node *np; | ||
| 72 | struct irq_domain *parent; | 88 | struct irq_domain *parent; |
| 73 | struct irq_domain *mc_msi_domain; | 89 | struct irq_domain *mc_msi_domain; |
| 74 | 90 | ||
| 91 | parent = irq_find_matching_fwnode(handle, DOMAIN_BUS_NEXUS); | ||
| 92 | if (!parent || !msi_get_domain_info(parent)) { | ||
| 93 | pr_err("%s: unable to locate ITS domain\n", name); | ||
| 94 | return; | ||
| 95 | } | ||
| 96 | |||
| 97 | mc_msi_domain = fsl_mc_msi_create_irq_domain(handle, | ||
| 98 | &its_fsl_mc_msi_domain_info, | ||
| 99 | parent); | ||
| 100 | if (!mc_msi_domain) { | ||
| 101 | pr_err("%s: unable to create fsl-mc domain\n", name); | ||
| 102 | return; | ||
| 103 | } | ||
| 104 | |||
| 105 | pr_info("fsl-mc MSI: %s domain created\n", name); | ||
| 106 | } | ||
| 107 | |||
| 108 | #ifdef CONFIG_ACPI | ||
| 109 | static int __init | ||
| 110 | its_fsl_mc_msi_parse_madt(union acpi_subtable_headers *header, | ||
| 111 | const unsigned long end) | ||
| 112 | { | ||
| 113 | struct acpi_madt_generic_translator *its_entry; | ||
| 114 | struct fwnode_handle *dom_handle; | ||
| 115 | const char *node_name; | ||
| 116 | int err = 0; | ||
| 117 | |||
| 118 | its_entry = (struct acpi_madt_generic_translator *)header; | ||
| 119 | node_name = kasprintf(GFP_KERNEL, "ITS@0x%lx", | ||
| 120 | (long)its_entry->base_address); | ||
| 121 | |||
| 122 | dom_handle = iort_find_domain_token(its_entry->translation_id); | ||
| 123 | if (!dom_handle) { | ||
| 124 | pr_err("%s: Unable to locate ITS domain handle\n", node_name); | ||
| 125 | err = -ENXIO; | ||
| 126 | goto out; | ||
| 127 | } | ||
| 128 | |||
| 129 | its_fsl_mc_msi_init_one(dom_handle, node_name); | ||
| 130 | |||
| 131 | out: | ||
| 132 | kfree(node_name); | ||
| 133 | return err; | ||
| 134 | } | ||
| 135 | |||
| 136 | |||
| 137 | static void __init its_fsl_mc_acpi_msi_init(void) | ||
| 138 | { | ||
| 139 | acpi_table_parse_madt(ACPI_MADT_TYPE_GENERIC_TRANSLATOR, | ||
| 140 | its_fsl_mc_msi_parse_madt, 0); | ||
| 141 | } | ||
| 142 | #else | ||
| 143 | static inline void its_fsl_mc_acpi_msi_init(void) { } | ||
| 144 | #endif | ||
| 145 | |||
| 146 | static void __init its_fsl_mc_of_msi_init(void) | ||
| 147 | { | ||
| 148 | struct device_node *np; | ||
| 149 | |||
| 75 | for (np = of_find_matching_node(NULL, its_device_id); np; | 150 | for (np = of_find_matching_node(NULL, its_device_id); np; |
| 76 | np = of_find_matching_node(np, its_device_id)) { | 151 | np = of_find_matching_node(np, its_device_id)) { |
| 77 | if (!of_device_is_available(np)) | 152 | if (!of_device_is_available(np)) |
| @@ -79,23 +154,15 @@ static int __init its_fsl_mc_msi_init(void) · 1 unmodified line | |||
| 79 | if (!of_property_read_bool(np, "msi-controller")) | 154 | if (!of_property_read_bool(np, "msi-controller")) |
| 80 | continue; | 155 | continue; |
| 81 | 156 | ||
| 82 | parent = irq_find_matching_host(np, DOMAIN_BUS_NEXUS); | 157 | its_fsl_mc_msi_init_one(of_node_to_fwnode(np), |
| 83 | if (!parent || !msi_get_domain_info(parent)) { | 158 | np->full_name); |
| 84 | pr_err("%pOF: unable to locate ITS domain\n", np); | ||
| 85 | continue; | ||
| 86 | } | ||
| 87 | |||
| 88 | mc_msi_domain = fsl_mc_msi_create_irq_domain( | ||
| 89 | of_node_to_fwnode(np), | ||
| 90 | &its_fsl_mc_msi_domain_info, | ||
| 91 | parent); | ||
| 92 | if (!mc_msi_domain) { | ||
| 93 | pr_err("%pOF: unable to create fsl-mc domain\n", np); | ||
| 94 | continue; | ||
| 95 | } | ||
| 96 | |||
| 97 | pr_info("fsl-mc MSI: %pOF domain created\n", np); | ||
| 98 | } | 159 | } |
| 160 | } | ||
| 161 | |||
| 162 | static int __init its_fsl_mc_msi_init(void) | ||
| 163 | { | ||
| 164 | its_fsl_mc_of_msi_init(); | ||
| 165 | its_fsl_mc_acpi_msi_init(); | ||
| 99 | 166 | ||
| 100 | return 0; | 167 | return 0; |
| 101 | } | 168 | } |
| @@ -2201,15 +2201,15 @@ int of_find_last_cache_level(unsigned int cpu) · 2200 unmodified lines | |||
| 2201 | } | 2201 | } |
| 2202 | 2202 | ||
| 2203 | /** | 2203 | /** |
| 2204 | * of_map_rid - Translate a requester ID through a downstream mapping. | 2204 | * of_map_id - Translate an ID through a downstream mapping. |
| 2205 | * @np: root complex device node. | 2205 | * @np: root complex device node. |
| 2206 | * @rid: device requester ID to map. | 2206 | * @id: device ID to map. |
| 2207 | * @map_name: property name of the map to use. | 2207 | * @map_name: property name of the map to use. |
| 2208 | * @map_mask_name: optional property name of the mask to use. | 2208 | * @map_mask_name: optional property name of the mask to use. |
| 2209 | * @target: optional pointer to a target device node. | 2209 | * @target: optional pointer to a target device node. |
| 2210 | * @id_out: optional pointer to receive the translated ID. | 2210 | * @id_out: optional pointer to receive the translated ID. |
| 2211 | * | 2211 | * |
| 2212 | * Given a device requester ID, look up the appropriate implementation-defined | 2212 | * Given a device ID, look up the appropriate implementation-defined |
| 2213 | * platform ID and/or the target device which receives transactions on that | 2213 | * platform ID and/or the target device which receives transactions on that |
| 2214 | * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or | 2214 | * ID, as per the "iommu-map" and "msi-map" bindings. Either of @target or |
| 2215 | * @id_out may be NULL if only the other is required. If @target points to | 2215 | * @id_out may be NULL if only the other is required. If @target points to |
| @@ -2219,11 +2219,11 @@ int of_find_last_cache_level(unsigned int cpu) · 3 unmodified lines | |||
| 2219 | * | 2219 | * |
| 2220 | * Return: 0 on success or a standard error code on failure. | 2220 | * Return: 0 on success or a standard error code on failure. |
| 2221 | */ | 2221 | */ |
| 2222 | int of_map_rid(struct device_node *np, u32 rid, | 2222 | int of_map_id(struct device_node *np, u32 id, |
| 2223 | const char *map_name, const char *map_mask_name, | 2223 | const char *map_name, const char *map_mask_name, |
| 2224 | struct device_node **target, u32 *id_out) | 2224 | struct device_node **target, u32 *id_out) |
| 2225 | { | 2225 | { |
| 2226 | u32 map_mask, masked_rid; | 2226 | u32 map_mask, masked_id; |
| 2227 | int map_len; | 2227 | int map_len; |
| 2228 | const __be32 *map = NULL; | 2228 | const __be32 *map = NULL; |
| 2229 | 2229 | ||
| @@ -2235,7 +2235,7 @@ int of_map_rid(struct device_node *np, u32 rid, · 5 unmodified lines | |||
| 2235 | if (target) | 2235 | if (target) |
| 2236 | return -ENODEV; | 2236 | return -ENODEV; |
| 2237 | /* Otherwise, no map implies no translation */ | 2237 | /* Otherwise, no map implies no translation */ |
| 2238 | *id_out = rid; | 2238 | *id_out = id; |
| 2239 | return 0; | 2239 | return 0; |
| 2240 | } | 2240 | } |
| 2241 | 2241 | ||
| @@ -2255,22 +2255,22 @@ int of_map_rid(struct device_node *np, u32 rid, · 13 unmodified lines | |||
| 2255 | if (map_mask_name) | 2255 | if (map_mask_name) |
| 2256 | of_property_read_u32(np, map_mask_name, &map_mask); | 2256 | of_property_read_u32(np, map_mask_name, &map_mask); |
| 2257 | 2257 | ||
| 2258 | masked_rid = map_mask & rid; | 2258 | masked_id = map_mask & id; |
| 2259 | for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { | 2259 | for ( ; map_len > 0; map_len -= 4 * sizeof(*map), map += 4) { |
| 2260 | struct device_node *phandle_node; | 2260 | struct device_node *phandle_node; |
| 2261 | u32 rid_base = be32_to_cpup(map + 0); | 2261 | u32 id_base = be32_to_cpup(map + 0); |
| 2262 | u32 phandle = be32_to_cpup(map + 1); | 2262 | u32 phandle = be32_to_cpup(map + 1); |
| 2263 | u32 out_base = be32_to_cpup(map + 2); | 2263 | u32 out_base = be32_to_cpup(map + 2); |
| 2264 | u32 rid_len = be32_to_cpup(map + 3); | 2264 | u32 id_len = be32_to_cpup(map + 3); |
| 2265 | 2265 | ||
| 2266 | if (rid_base & ~map_mask) { | 2266 | if (id_base & ~map_mask) { |
| 2267 | pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores rid-base (0x%x)\n", | 2267 | pr_err("%pOF: Invalid %s translation - %s-mask (0x%x) ignores id-base (0x%x)\n", |
| 2268 | np, map_name, map_name, | 2268 | np, map_name, map_name, |
| 2269 | map_mask, rid_base); | 2269 | map_mask, id_base); |
| 2270 | return -EFAULT; | 2270 | return -EFAULT; |
| 2271 | } | 2271 | } |
| 2272 | 2272 | ||
| 2273 | if (masked_rid < rid_base || masked_rid >= rid_base + rid_len) | 2273 | if (masked_id < id_base || masked_id >= id_base + id_len) |
| 2274 | continue; | 2274 | continue; |
| 2275 | 2275 | ||
| 2276 | phandle_node = of_find_node_by_phandle(phandle); | 2276 | phandle_node = of_find_node_by_phandle(phandle); |
| @@ -2288,20 +2288,20 @@ int of_map_rid(struct device_node *np, u32 rid, · 11 unmodified lines | |||
| 2288 | } | 2288 | } |
| 2289 | 2289 | ||
| 2290 | if (id_out) | 2290 | if (id_out) |
| 2291 | *id_out = masked_rid - rid_base + out_base; | 2291 | *id_out = masked_id - id_base + out_base; |
| 2292 | 2292 | ||
| 2293 | pr_debug("%pOF: %s, using mask %08x, rid-base: %08x, out-base: %08x, length: %08x, rid: %08x -> %08x\n", | 2293 | pr_debug("%pOF: %s, using mask %08x, id-base: %08x, out-base: %08x, length: %08x, id: %08x -> %08x\n", |
| 2294 | np, map_name, map_mask, rid_base, out_base, | 2294 | np, map_name, map_mask, id_base, out_base, |
| 2295 | rid_len, rid, masked_rid - rid_base + out_base); | 2295 | id_len, id, masked_id - id_base + out_base); |
| 2296 | return 0; | 2296 | return 0; |
| 2297 | } | 2297 | } |
| 2298 | 2298 | ||
| 2299 | pr_info("%pOF: no %s translation for rid 0x%x on %pOF\n", np, map_name, | 2299 | pr_info("%pOF: no %s translation for id 0x%x on %pOF\n", np, map_name, |
| 2300 | rid, target && *target ? *target : NULL); | 2300 | id, target && *target ? *target : NULL); |
| 2301 | 2301 | ||
| 2302 | /* Bypasses translation */ | 2302 | /* Bypasses translation */ |
| 2303 | if (id_out) | 2303 | if (id_out) |
| 2304 | *id_out = rid; | 2304 | *id_out = id; |
| 2305 | return 0; | 2305 | return 0; |
| 2306 | } | 2306 | } |
| 2307 | EXPORT_SYMBOL_GPL(of_map_rid); | 2307 | EXPORT_SYMBOL_GPL(of_map_id); |
| @@ -78,6 +78,7 @@ int of_device_add(struct platform_device *ofdev) · 77 unmodified lines | |||
| 78 | * @np: Pointer to OF node having DMA configuration | 78 | * @np: Pointer to OF node having DMA configuration |
| 79 | * @force_dma: Whether device is to be set up by of_dma_configure() even if | 79 | * @force_dma: Whether device is to be set up by of_dma_configure() even if |
| 80 | * DMA capability is not explicitly described by firmware. | 80 | * DMA capability is not explicitly described by firmware. |
| 81 | * @id: Optional const pointer value input id | ||
| 81 | * | 82 | * |
| 82 | * Try to get devices's DMA configuration from DT and update it | 83 | * Try to get devices's DMA configuration from DT and update it |
| 83 | * accordingly. | 84 | * accordingly. |
| @@ -86,7 +87,8 @@ int of_device_add(struct platform_device *ofdev) · 2 unmodified lines | |||
| 86 | * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events | 87 | * can use a platform bus notifier and handle BUS_NOTIFY_ADD_DEVICE events |
| 87 | * to fix up DMA configuration. | 88 | * to fix up DMA configuration. |
| 88 | */ | 89 | */ |
| 89 | int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) | 90 | int of_dma_configure_id(struct device *dev, struct device_node *np, |
| 91 | bool force_dma, const u32 *id) | ||
| 90 | { | 92 | { |
| 91 | u64 dma_addr, paddr, size = 0; | 93 | u64 dma_addr, paddr, size = 0; |
| 92 | int ret; | 94 | int ret; |
| @@ -160,7 +162,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) · 67 unmodified lines | |||
| 160 | dev_dbg(dev, "device is%sdma coherent\n", | 162 | dev_dbg(dev, "device is%sdma coherent\n", |
| 161 | coherent ? " " : " not "); | 163 | coherent ? " " : " not "); |
| 162 | 164 | ||
| 163 | iommu = of_iommu_configure(dev, np); | 165 | iommu = of_iommu_configure(dev, np, id); |
| 164 | if (PTR_ERR(iommu) == -EPROBE_DEFER) | 166 | if (PTR_ERR(iommu) == -EPROBE_DEFER) |
| 165 | return -EPROBE_DEFER; | 167 | return -EPROBE_DEFER; |
| 166 | 168 | ||
| @@ -171,7 +173,7 @@ int of_dma_configure(struct device *dev, struct device_node *np, bool force_dma) · 4 unmodified lines | |||
| 171 | 173 | ||
| 172 | return 0; | 174 | return 0; |
| 173 | } | 175 | } |
| 174 | EXPORT_SYMBOL_GPL(of_dma_configure); | 176 | EXPORT_SYMBOL_GPL(of_dma_configure_id); |
| 175 | 177 | ||
| 176 | int of_device_register(struct platform_device *pdev) | 178 | int of_device_register(struct platform_device *pdev) |
| 177 | { | 179 | { |
| @@ -576,55 +576,57 @@ err: · 575 unmodified lines | |||
| 576 | } | 576 | } |
| 577 | } | 577 | } |
| 578 | 578 | ||
| 579 | static u32 __of_msi_map_rid(struct device *dev, struct device_node **np, | 579 | static u32 __of_msi_map_id(struct device *dev, struct device_node **np, |
| 580 | u32 rid_in) | 580 | u32 id_in) |
| 581 | { | 581 | { |
| 582 | struct device *parent_dev; | 582 | struct device *parent_dev; |
| 583 | u32 rid_out = rid_in; | 583 | u32 id_out = id_in; |
| 584 | 584 | ||
| 585 | /* | 585 | /* |
| 586 | * Walk up the device parent links looking for one with a | 586 | * Walk up the device parent links looking for one with a |
| 587 | * "msi-map" property. | 587 | * "msi-map" property. |
| 588 | */ | 588 | */ |
| 589 | for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) | 589 | for (parent_dev = dev; parent_dev; parent_dev = parent_dev->parent) |
| 590 | if (!of_map_rid(parent_dev->of_node, rid_in, "msi-map", | 590 | if (!of_map_id(parent_dev->of_node, id_in, "msi-map", |
| 591 | "msi-map-mask", np, &rid_out)) | 591 | "msi-map-mask", np, &id_out)) |
| 592 | break; | 592 | break; |
| 593 | return rid_out; | 593 | return id_out; |
| 594 | } | 594 | } |
| 595 | 595 | ||
| 596 | /** | 596 | /** |
| 597 | * of_msi_map_rid - Map a MSI requester ID for a device. | 597 | * of_msi_map_id - Map a MSI ID for a device. |
| 598 | * @dev: device for which the mapping is to be done. | 598 | * @dev: device for which the mapping is to be done. |
| 599 | * @msi_np: device node of the expected msi controller. | 599 | * @msi_np: device node of the expected msi controller. |
| 600 | * @rid_in: unmapped MSI requester ID for the device. | 600 | * @id_in: unmapped MSI ID for the device. |
| 601 | * | 601 | * |
| 602 | * Walk up the device hierarchy looking for devices with a "msi-map" | 602 | * Walk up the device hierarchy looking for devices with a "msi-map" |
| 603 | * property. If found, apply the mapping to @rid_in. | 603 | * property. If found, apply the mapping to @id_in. |
| 604 | * | 604 | * |
| 605 | * Returns the mapped MSI requester ID. | 605 | * Returns the mapped MSI ID. |
| 606 | */ | 606 | */ |
| 607 | u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in) | 607 | u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in) |
| 608 | { | 608 | { |
| 609 | return __of_msi_map_rid(dev, &msi_np, rid_in); | 609 | return __of_msi_map_id(dev, &msi_np, id_in); |
| 610 | } | 610 | } |
| 611 | 611 | ||
| 612 | /** | 612 | /** |
| 613 | * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain | 613 | * of_msi_map_get_device_domain - Use msi-map to find the relevant MSI domain |
| 614 | * @dev: device for which the mapping is to be done. | 614 | * @dev: device for which the mapping is to be done. |
| 615 | * @rid: Requester ID for the device. | 615 | * @id: Device ID. |
| 616 | * @bus_token: Bus token | ||
| 616 | * | 617 | * |
| 617 | * Walk up the device hierarchy looking for devices with a "msi-map" | 618 | * Walk up the device hierarchy looking for devices with a "msi-map" |
| 618 | * property. | 619 | * property. |
| 619 | * | 620 | * |
| 620 | * Returns: the MSI domain for this device (or NULL on failure) | 621 | * Returns: the MSI domain for this device (or NULL on failure) |
| 621 | */ | 622 | */ |
| 622 | struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 rid) | 623 | struct irq_domain *of_msi_map_get_device_domain(struct device *dev, u32 id, |
| 624 | u32 bus_token) | ||
| 623 | { | 625 | { |
| 624 | struct device_node *np = NULL; | 626 | struct device_node *np = NULL; |
| 625 | 627 | ||
| 626 | __of_msi_map_rid(dev, &np, rid); | 628 | __of_msi_map_id(dev, &np, id); |
| 627 | return irq_find_matching_host(np, DOMAIN_BUS_PCI_MSI); | 629 | return irq_find_matching_host(np, bus_token); |
| 628 | } | 630 | } |
| 629 | 631 | ||
| 630 | /** | 632 | /** |
| @@ -1535,8 +1535,8 @@ u32 pci_msi_domain_get_msi_rid(struct irq_domain *domain, struct pci_dev *pdev) · 1534 unmodified lines | |||
| 1535 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); | 1535 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); |
| 1536 | 1536 | ||
| 1537 | of_node = irq_domain_get_of_node(domain); | 1537 | of_node = irq_domain_get_of_node(domain); |
| 1538 | rid = of_node ? of_msi_map_rid(&pdev->dev, of_node, rid) : | 1538 | rid = of_node ? of_msi_map_id(&pdev->dev, of_node, rid) : |
| 1539 | iort_msi_map_rid(&pdev->dev, rid); | 1539 | iort_msi_map_id(&pdev->dev, rid); |
| 1540 | 1540 | ||
| 1541 | return rid; | 1541 | return rid; |
| 1542 | } | 1542 | } |
| @@ -1556,9 +1556,10 @@ struct irq_domain *pci_msi_get_device_domain(struct pci_dev *pdev) · 13 unmodified lines | |||
| 1556 | u32 rid = pci_dev_id(pdev); | 1556 | u32 rid = pci_dev_id(pdev); |
| 1557 | 1557 | ||
| 1558 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); | 1558 | pci_for_each_dma_alias(pdev, get_msi_id_cb, &rid); |
| 1559 | dom = of_msi_map_get_device_domain(&pdev->dev, rid); | 1559 | dom = of_msi_map_get_device_domain(&pdev->dev, rid, DOMAIN_BUS_PCI_MSI); |
| 1560 | if (!dom) | 1560 | if (!dom) |
| 1561 | dom = iort_get_device_domain(&pdev->dev, rid); | 1561 | dom = iort_get_device_domain(&pdev->dev, rid, |
| 1562 | DOMAIN_BUS_PCI_MSI); | ||
| 1562 | return dom; | 1563 | return dom; |
| 1563 | } | 1564 | } |
| 1564 | #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */ | 1565 | #endif /* CONFIG_PCI_MSI_IRQ_DOMAIN */ |
| @@ -756,8 +756,7 @@ static int smmu_pmu_probe(struct platform_device *pdev) · 755 unmodified lines | |||
| 756 | .capabilities = PERF_PMU_CAP_NO_EXCLUDE, | 756 | .capabilities = PERF_PMU_CAP_NO_EXCLUDE, |
| 757 | }; | 757 | }; |
| 758 | 758 | ||
| 759 | res_0 = platform_get_resource(pdev, IORESOURCE_MEM, 0); | 759 | smmu_pmu->reg_base = devm_platform_get_and_ioremap_resource(pdev, 0, &res_0); |
| 760 | smmu_pmu->reg_base = devm_ioremap_resource(dev, res_0); | ||
| 761 | if (IS_ERR(smmu_pmu->reg_base)) | 760 | if (IS_ERR(smmu_pmu->reg_base)) |
| 762 | return PTR_ERR(smmu_pmu->reg_base); | 761 | return PTR_ERR(smmu_pmu->reg_base); |
| 763 | 762 | ||
| @@ -2092,11 +2092,6 @@ static int get_indirect(struct vhost_virtqueue *vq, · 2091 unmodified lines | |||
| 2092 | return ret; | 2092 | return ret; |
| 2093 | } | 2093 | } |
| 2094 | iov_iter_init(&from, READ, vq->indirect, ret, len); | 2094 | iov_iter_init(&from, READ, vq->indirect, ret, len); |
| 2095 | |||
| 2096 | /* We will use the result as an address to read from, so most | ||
| 2097 | * architectures only need a compiler barrier here. */ | ||
| 2098 | read_barrier_depends(); | ||
| 2099 | |||
| 2100 | count = len / sizeof desc; | 2095 | count = len / sizeof desc; |
| 2101 | /* Buffers are chained via a 16 bit next field, so | 2096 | /* Buffers are chained via a 16 bit next field, so |
| 2102 | * we can have at most 2^16 of these. */ | 2097 | * we can have at most 2^16 of these. */ |
| @@ -588,8 +588,13 @@ bool acpi_dma_supported(struct acpi_device *adev); · 587 unmodified lines | |||
| 588 | enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev); | 588 | enum dev_dma_attr acpi_get_dma_attr(struct acpi_device *adev); |
| 589 | int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset, | 589 | int acpi_dma_get_range(struct device *dev, u64 *dma_addr, u64 *offset, |
| 590 | u64 *size); | 590 | u64 *size); |
| 591 | int acpi_dma_configure(struct device *dev, enum dev_dma_attr attr); | 591 | int acpi_dma_configure_id(struct device *dev, enum dev_dma_attr attr, |
| 592 | 592 | const u32 *input_id); | |
| 593 | static inline int acpi_dma_configure(struct device *dev, | ||
| 594 | enum dev_dma_attr attr) | ||
| 595 | { | ||
| 596 | return acpi_dma_configure_id(dev, attr, NULL); | ||
| 597 | } | ||
| 593 | struct acpi_device *acpi_find_child_device(struct acpi_device *parent, | 598 | struct acpi_device *acpi_find_child_device(struct acpi_device *parent, |
| 594 | u64 address, bool check_children); | 599 | u64 address, bool check_children); |
| 595 | int acpi_is_root_bridge(acpi_handle); | 600 | int acpi_is_root_bridge(acpi_handle); |
| @@ -45,6 +45,7 @@ mandatory-y += pci.h · 44 unmodified lines | |||
| 45 | mandatory-y += percpu.h | 45 | mandatory-y += percpu.h |
| 46 | mandatory-y += pgalloc.h | 46 | mandatory-y += pgalloc.h |
| 47 | mandatory-y += preempt.h | 47 | mandatory-y += preempt.h |
| 48 | mandatory-y += rwonce.h | ||
| 48 | mandatory-y += sections.h | 49 | mandatory-y += sections.h |
| 49 | mandatory-y += serial.h | 50 | mandatory-y += serial.h |
| 50 | mandatory-y += shmparam.h | 51 | mandatory-y += shmparam.h |
| @@ -13,7 +13,7 @@ · 12 unmodified lines | |||
| 13 | 13 | ||
| 14 | #ifndef __ASSEMBLY__ | 14 | #ifndef __ASSEMBLY__ |
| 15 | 15 | ||
| 16 | #include <linux/compiler.h> | 16 | #include <asm/rwonce.h> |
| 17 | 17 | ||
| 18 | #ifndef nop | 18 | #ifndef nop |
| 19 | #define nop() asm volatile ("nop") | 19 | #define nop() asm volatile ("nop") |
| @@ -46,10 +46,6 @@ · 26 unmodified lines | |||
| 46 | #define dma_wmb() wmb() | 46 | #define dma_wmb() wmb() |
| 47 | #endif | 47 | #endif |
| 48 | 48 | ||
| 49 | #ifndef read_barrier_depends | ||
| 50 | #define read_barrier_depends() do { } while (0) | ||
| 51 | #endif | ||
| 52 | |||
| 53 | #ifndef __smp_mb | 49 | #ifndef __smp_mb |
| 54 | #define __smp_mb() mb() | 50 | #define __smp_mb() mb() |
| 55 | #endif | 51 | #endif |
| @@ -62,10 +58,6 @@ · 6 unmodified lines | |||
| 62 | #define __smp_wmb() wmb() | 58 | #define __smp_wmb() wmb() |
| 63 | #endif | 59 | #endif |
| 64 | 60 | ||
| 65 | #ifndef __smp_read_barrier_depends | ||
| 66 | #define __smp_read_barrier_depends() read_barrier_depends() | ||
| 67 | #endif | ||
| 68 | |||
| 69 | #ifdef CONFIG_SMP | 61 | #ifdef CONFIG_SMP |
| 70 | 62 | ||
| 71 | #ifndef smp_mb | 63 | #ifndef smp_mb |
| @@ -80,10 +72,6 @@ · 8 unmodified lines | |||
| 80 | #define smp_wmb() __smp_wmb() | 72 | #define smp_wmb() __smp_wmb() |
| 81 | #endif | 73 | #endif |
| 82 | 74 | ||
| 83 | #ifndef smp_read_barrier_depends | ||
| 84 | #define smp_read_barrier_depends() __smp_read_barrier_depends() | ||
| 85 | #endif | ||
| 86 | |||
| 87 | #else /* !CONFIG_SMP */ | 75 | #else /* !CONFIG_SMP */ |
| 88 | 76 | ||
| 89 | #ifndef smp_mb | 77 | #ifndef smp_mb |
| @@ -98,10 +86,6 @@ · 8 unmodified lines | |||
| 98 | #define smp_wmb() barrier() | 86 | #define smp_wmb() barrier() |
| 99 | #endif | 87 | #endif |
| 100 | 88 | ||
| 101 | #ifndef smp_read_barrier_depends | ||
| 102 | #define smp_read_barrier_depends() do { } while (0) | ||
| 103 | #endif | ||
| 104 | |||
| 105 | #endif /* CONFIG_SMP */ | 89 | #endif /* CONFIG_SMP */ |
| 106 | 90 | ||
| 107 | #ifndef __smp_store_mb | 91 | #ifndef __smp_store_mb |
| @@ -196,7 +180,6 @@ do { \ · 88 unmodified lines | |||
| 196 | #define virt_mb() __smp_mb() | 180 | #define virt_mb() __smp_mb() |
| 197 | #define virt_rmb() __smp_rmb() | 181 | #define virt_rmb() __smp_rmb() |
| 198 | #define virt_wmb() __smp_wmb() | 182 | #define virt_wmb() __smp_wmb() |
| 199 | #define virt_read_barrier_depends() __smp_read_barrier_depends() | ||
| 200 | #define virt_store_mb(var, value) __smp_store_mb(var, value) | 183 | #define virt_store_mb(var, value) __smp_store_mb(var, value) |
| 201 | #define virt_mb__before_atomic() __smp_mb__before_atomic() | 184 | #define virt_mb__before_atomic() __smp_mb__before_atomic() |
| 202 | #define virt_mb__after_atomic() __smp_mb__after_atomic() | 185 | #define virt_mb__after_atomic() __smp_mb__after_atomic() |
| @@ -0,0 +1,90 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 */ | ||
| 2 | /* | ||
| 3 | * Prevent the compiler from merging or refetching reads or writes. The | ||
| 4 | * compiler is also forbidden from reordering successive instances of | ||
| 5 | * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some | ||
| 6 | * particular ordering. One way to make the compiler aware of ordering is to | ||
| 7 | * put the two invocations of READ_ONCE or WRITE_ONCE in different C | ||
| 8 | * statements. | ||
| 9 | * | ||
| 10 | * These two macros will also work on aggregate data types like structs or | ||
| 11 | * unions. | ||
| 12 | * | ||
| 13 | * Their two major use cases are: (1) Mediating communication between | ||
| 14 | * process-level code and irq/NMI handlers, all running on the same CPU, | ||
| 15 | * and (2) Ensuring that the compiler does not fold, spindle, or otherwise | ||
| 16 | * mutilate accesses that either do not require ordering or that interact | ||
| 17 | * with an explicit memory barrier or atomic instruction that provides the | ||
| 18 | * required ordering. | ||
| 19 | */ | ||
| 20 | #ifndef __ASM_GENERIC_RWONCE_H | ||
| 21 | #define __ASM_GENERIC_RWONCE_H | ||
| 22 | |||
| 23 | #ifndef __ASSEMBLY__ | ||
| 24 | |||
| 25 | #include <linux/compiler_types.h> | ||
| 26 | #include <linux/kasan-checks.h> | ||
| 27 | #include <linux/kcsan-checks.h> | ||
| 28 | |||
| 29 | /* | ||
| 30 | * Yes, this permits 64-bit accesses on 32-bit architectures. These will | ||
| 31 | * actually be atomic in some cases (namely Armv7 + LPAE), but for others we | ||
| 32 | * rely on the access being split into 2x32-bit accesses for a 32-bit quantity | ||
| 33 | * (e.g. a virtual address) and a strong prevailing wind. | ||
| 34 | */ | ||
| 35 | #define compiletime_assert_rwonce_type(t) \ | ||
| 36 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \ | ||
| 37 | "Unsupported access size for {READ,WRITE}_ONCE().") | ||
| 38 | |||
| 39 | /* | ||
| 40 | * Use __READ_ONCE() instead of READ_ONCE() if you do not require any | ||
| 41 | * atomicity. Note that this may result in tears! | ||
| 42 | */ | ||
| 43 | #ifndef __READ_ONCE | ||
| 44 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x)) | ||
| 45 | #endif | ||
| 46 | |||
| 47 | #define READ_ONCE(x) \ | ||
| 48 | ({ \ | ||
| 49 | compiletime_assert_rwonce_type(x); \ | ||
| 50 | __READ_ONCE(x); \ | ||
| 51 | }) | ||
| 52 | |||
| 53 | #define __WRITE_ONCE(x, val) \ | ||
| 54 | do { \ | ||
| 55 | *(volatile typeof(x) *)&(x) = (val); \ | ||
| 56 | } while (0) | ||
| 57 | |||
| 58 | #define WRITE_ONCE(x, val) \ | ||
| 59 | do { \ | ||
| 60 | compiletime_assert_rwonce_type(x); \ | ||
| 61 | __WRITE_ONCE(x, val); \ | ||
| 62 | } while (0) | ||
| 63 | |||
| 64 | static __no_sanitize_or_inline | ||
| 65 | unsigned long __read_once_word_nocheck(const void *addr) | ||
| 66 | { | ||
| 67 | return __READ_ONCE(*(unsigned long *)addr); | ||
| 68 | } | ||
| 69 | |||
| 70 | /* | ||
| 71 | * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need to load a | ||
| 72 | * word from memory atomically but without telling KASAN/KCSAN. This is | ||
| 73 | * usually used by unwinding code when walking the stack of a running process. | ||
| 74 | */ | ||
| 75 | #define READ_ONCE_NOCHECK(x) \ | ||
| 76 | ({ \ | ||
| 77 | compiletime_assert(sizeof(x) == sizeof(unsigned long), \ | ||
| 78 | "Unsupported access size for READ_ONCE_NOCHECK()."); \ | ||
| 79 | (typeof(x))__read_once_word_nocheck(&(x)); \ | ||
| 80 | }) | ||
| 81 | |||
| 82 | static __no_kasan_or_inline | ||
| 83 | unsigned long read_word_at_a_time(const void *addr) | ||
| 84 | { | ||
| 85 | kasan_check_read(addr, 1); | ||
| 86 | return *(unsigned long *)addr; | ||
| 87 | } | ||
| 88 | |||
| 89 | #endif /* __ASSEMBLY__ */ | ||
| 90 | #endif /* __ASM_GENERIC_RWONCE_H */ | ||
| @@ -512,6 +512,38 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm · 511 unmodified lines | |||
| 512 | } | 512 | } |
| 513 | #endif | 513 | #endif |
| 514 | 514 | ||
| 515 | /* | ||
| 516 | * tlb_flush_{pte|pmd|pud|p4d}_range() adjust the tlb->start and tlb->end, | ||
| 517 | * and set corresponding cleared_*. | ||
| 518 | */ | ||
| 519 | static inline void tlb_flush_pte_range(struct mmu_gather *tlb, | ||
| 520 | unsigned long address, unsigned long size) | ||
| 521 | { | ||
| 522 | __tlb_adjust_range(tlb, address, size); | ||
| 523 | tlb->cleared_ptes = 1; | ||
| 524 | } | ||
| 525 | |||
| 526 | static inline void tlb_flush_pmd_range(struct mmu_gather *tlb, | ||
| 527 | unsigned long address, unsigned long size) | ||
| 528 | { | ||
| 529 | __tlb_adjust_range(tlb, address, size); | ||
| 530 | tlb->cleared_pmds = 1; | ||
| 531 | } | ||
| 532 | |||
| 533 | static inline void tlb_flush_pud_range(struct mmu_gather *tlb, | ||
| 534 | unsigned long address, unsigned long size) | ||
| 535 | { | ||
| 536 | __tlb_adjust_range(tlb, address, size); | ||
| 537 | tlb->cleared_puds = 1; | ||
| 538 | } | ||
| 539 | |||
| 540 | static inline void tlb_flush_p4d_range(struct mmu_gather *tlb, | ||
| 541 | unsigned long address, unsigned long size) | ||
| 542 | { | ||
| 543 | __tlb_adjust_range(tlb, address, size); | ||
| 544 | tlb->cleared_p4ds = 1; | ||
| 545 | } | ||
| 546 | |||
| 515 | #ifndef __tlb_remove_tlb_entry | 547 | #ifndef __tlb_remove_tlb_entry |
| 516 | #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) | 548 | #define __tlb_remove_tlb_entry(tlb, ptep, address) do { } while (0) |
| 517 | #endif | 549 | #endif |
| @@ -525,19 +557,17 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm · 7 unmodified lines | |||
| 525 | */ | 557 | */ |
| 526 | #define tlb_remove_tlb_entry(tlb, ptep, address) \ | 558 | #define tlb_remove_tlb_entry(tlb, ptep, address) \ |
| 527 | do { \ | 559 | do { \ |
| 528 | __tlb_adjust_range(tlb, address, PAGE_SIZE); \ | 560 | tlb_flush_pte_range(tlb, address, PAGE_SIZE); \ |
| 529 | tlb->cleared_ptes = 1; \ | ||
| 530 | __tlb_remove_tlb_entry(tlb, ptep, address); \ | 561 | __tlb_remove_tlb_entry(tlb, ptep, address); \ |
| 531 | } while (0) | 562 | } while (0) |
| 532 | 563 | ||
| 533 | #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address) \ | 564 | #define tlb_remove_huge_tlb_entry(h, tlb, ptep, address) \ |
| 534 | do { \ | 565 | do { \ |
| 535 | unsigned long _sz = huge_page_size(h); \ | 566 | unsigned long _sz = huge_page_size(h); \ |
| 536 | __tlb_adjust_range(tlb, address, _sz); \ | ||
| 537 | if (_sz == PMD_SIZE) \ | 567 | if (_sz == PMD_SIZE) \ |
| 538 | tlb->cleared_pmds = 1; \ | 568 | tlb_flush_pmd_range(tlb, address, _sz); \ |
| 539 | else if (_sz == PUD_SIZE) \ | 569 | else if (_sz == PUD_SIZE) \ |
| 540 | tlb->cleared_puds = 1; \ | 570 | tlb_flush_pud_range(tlb, address, _sz); \ |
| 541 | __tlb_remove_tlb_entry(tlb, ptep, address); \ | 571 | __tlb_remove_tlb_entry(tlb, ptep, address); \ |
| 542 | } while (0) | 572 | } while (0) |
| 543 | 573 | ||
| @@ -551,8 +581,7 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm · 7 unmodified lines | |||
| 551 | 581 | ||
| 552 | #define tlb_remove_pmd_tlb_entry(tlb, pmdp, address) \ | 582 | #define tlb_remove_pmd_tlb_entry(tlb, pmdp, address) \ |
| 553 | do { \ | 583 | do { \ |
| 554 | __tlb_adjust_range(tlb, address, HPAGE_PMD_SIZE); \ | 584 | tlb_flush_pmd_range(tlb, address, HPAGE_PMD_SIZE); \ |
| 555 | tlb->cleared_pmds = 1; \ | ||
| 556 | __tlb_remove_pmd_tlb_entry(tlb, pmdp, address); \ | 585 | __tlb_remove_pmd_tlb_entry(tlb, pmdp, address); \ |
| 557 | } while (0) | 586 | } while (0) |
| 558 | 587 | ||
| @@ -566,8 +595,7 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm · 7 unmodified lines | |||
| 566 | 595 | ||
| 567 | #define tlb_remove_pud_tlb_entry(tlb, pudp, address) \ | 596 | #define tlb_remove_pud_tlb_entry(tlb, pudp, address) \ |
| 568 | do { \ | 597 | do { \ |
| 569 | __tlb_adjust_range(tlb, address, HPAGE_PUD_SIZE); \ | 598 | tlb_flush_pud_range(tlb, address, HPAGE_PUD_SIZE); \ |
| 570 | tlb->cleared_puds = 1; \ | ||
| 571 | __tlb_remove_pud_tlb_entry(tlb, pudp, address); \ | 599 | __tlb_remove_pud_tlb_entry(tlb, pudp, address); \ |
| 572 | } while (0) | 600 | } while (0) |
| 573 | 601 | ||
| @@ -592,9 +620,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm · 18 unmodified lines | |||
| 592 | #ifndef pte_free_tlb | 620 | #ifndef pte_free_tlb |
| 593 | #define pte_free_tlb(tlb, ptep, address) \ | 621 | #define pte_free_tlb(tlb, ptep, address) \ |
| 594 | do { \ | 622 | do { \ |
| 595 | __tlb_adjust_range(tlb, address, PAGE_SIZE); \ | 623 | tlb_flush_pmd_range(tlb, address, PAGE_SIZE); \ |
| 596 | tlb->freed_tables = 1; \ | 624 | tlb->freed_tables = 1; \ |
| 597 | tlb->cleared_pmds = 1; \ | ||
| 598 | __pte_free_tlb(tlb, ptep, address); \ | 625 | __pte_free_tlb(tlb, ptep, address); \ |
| 599 | } while (0) | 626 | } while (0) |
| 600 | #endif | 627 | #endif |
| @@ -602,9 +629,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm · 1 unmodified line | |||
| 602 | #ifndef pmd_free_tlb | 629 | #ifndef pmd_free_tlb |
| 603 | #define pmd_free_tlb(tlb, pmdp, address) \ | 630 | #define pmd_free_tlb(tlb, pmdp, address) \ |
| 604 | do { \ | 631 | do { \ |
| 605 | __tlb_adjust_range(tlb, address, PAGE_SIZE); \ | 632 | tlb_flush_pud_range(tlb, address, PAGE_SIZE); \ |
| 606 | tlb->freed_tables = 1; \ | 633 | tlb->freed_tables = 1; \ |
| 607 | tlb->cleared_puds = 1; \ | ||
| 608 | __pmd_free_tlb(tlb, pmdp, address); \ | 634 | __pmd_free_tlb(tlb, pmdp, address); \ |
| 609 | } while (0) | 635 | } while (0) |
| 610 | #endif | 636 | #endif |
| @@ -612,9 +638,8 @@ static inline void tlb_end_vma(struct mmu_gather *tlb, struct vm_area_struct *vm · 1 unmodified line | |||
| 612 | #ifndef pud_free_tlb | 638 | #ifndef pud_free_tlb |
| 613 | #define pud_free_tlb(tlb, pudp, address) \ | 639 | #define pud_free_tlb(tlb, pudp, address) \ |
| 614 | do { \ | 640 | do { \ |
| 615 | __tlb_adjust_range(tlb, address, PAGE_SIZE); \ | 641 | tlb_flush_p4d_range(tlb, address, PAGE_SIZE); \ |
| 616 | tlb->freed_tables = 1; \ | 642 | tlb->freed_tables = 1; \ |
| 617 | tlb->cleared_p4ds = 1; \ | ||
| 618 | __pud_free_tlb(tlb, pudp, address); \ | 643 | __pud_free_tlb(tlb, pudp, address); \ |
| 619 | } while (0) | 644 | } while (0) |
| 620 | #endif | 645 | #endif |
| @@ -905,6 +905,13 @@ static inline int acpi_dma_configure(struct device *dev, · 904 unmodified lines | |||
| 905 | return 0; | 905 | return 0; |
| 906 | } | 906 | } |
| 907 | 907 | ||
| 908 | static inline int acpi_dma_configure_id(struct device *dev, | ||
| 909 | enum dev_dma_attr attr, | ||
| 910 | const u32 *input_id) | ||
| 911 | { | ||
| 912 | return 0; | ||
| 913 | } | ||
| 914 | |||
| 908 | #define ACPI_PTR(_ptr) (NULL) | 915 | #define ACPI_PTR(_ptr) (NULL) |
| 909 | 916 | ||
| 910 | static inline void acpi_device_set_enumerated(struct acpi_device *adev) | 917 | static inline void acpi_device_set_enumerated(struct acpi_device *adev) |
| @@ -28,27 +28,29 @@ void iort_deregister_domain_token(int trans_id); · 27 unmodified lines | |||
| 28 | struct fwnode_handle *iort_find_domain_token(int trans_id); | 28 | struct fwnode_handle *iort_find_domain_token(int trans_id); |
| 29 | #ifdef CONFIG_ACPI_IORT | 29 | #ifdef CONFIG_ACPI_IORT |
| 30 | void acpi_iort_init(void); | 30 | void acpi_iort_init(void); |
| 31 | u32 iort_msi_map_rid(struct device *dev, u32 req_id); | 31 | u32 iort_msi_map_id(struct device *dev, u32 id); |
| 32 | struct irq_domain *iort_get_device_domain(struct device *dev, u32 req_id); | 32 | struct irq_domain *iort_get_device_domain(struct device *dev, u32 id, |
| 33 | enum irq_domain_bus_token bus_token); | ||
| 33 | void acpi_configure_pmsi_domain(struct device *dev); | 34 | void acpi_configure_pmsi_domain(struct device *dev); |
| 34 | int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id); | 35 | int iort_pmsi_get_dev_id(struct device *dev, u32 *dev_id); |
| 35 | /* IOMMU interface */ | 36 | /* IOMMU interface */ |
| 36 | void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size); | 37 | void iort_dma_setup(struct device *dev, u64 *dma_addr, u64 *size); |
| 37 | const struct iommu_ops *iort_iommu_configure(struct device *dev); | 38 | const struct iommu_ops *iort_iommu_configure_id(struct device *dev, |
| 39 | const u32 *id_in); | ||
| 38 | int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head); | 40 | int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head); |
| 39 | #else | 41 | #else |
| 40 | static inline void acpi_iort_init(void) { } | 42 | static inline void acpi_iort_init(void) { } |
| 41 | static inline u32 iort_msi_map_rid(struct device *dev, u32 req_id) | 43 | static inline u32 iort_msi_map_id(struct device *dev, u32 id) |
| 42 | { return req_id; } | 44 | { return id; } |
| 43 | static inline struct irq_domain *iort_get_device_domain(struct device *dev, | 45 | static inline struct irq_domain *iort_get_device_domain( |
| 44 | u32 req_id) | 46 | struct device *dev, u32 id, enum irq_domain_bus_token bus_token) |
| 45 | { return NULL; } | 47 | { return NULL; } |
| 46 | static inline void acpi_configure_pmsi_domain(struct device *dev) { } | 48 | static inline void acpi_configure_pmsi_domain(struct device *dev) { } |
| 47 | /* IOMMU interface */ | 49 | /* IOMMU interface */ |
| 48 | static inline void iort_dma_setup(struct device *dev, u64 *dma_addr, | 50 | static inline void iort_dma_setup(struct device *dev, u64 *dma_addr, |
| 49 | u64 *size) { } | 51 | u64 *size) { } |
| 50 | static inline const struct iommu_ops *iort_iommu_configure( | 52 | static inline const struct iommu_ops *iort_iommu_configure_id( |
| 51 | struct device *dev) | 53 | struct device *dev, const u32 *id_in) |
| 52 | { return NULL; } | 54 | { return NULL; } |
| 53 | static inline | 55 | static inline |
| 54 | int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) | 56 | int iort_iommu_msi_get_resv_regions(struct device *dev, struct list_head *head) |
| @@ -81,6 +81,28 @@ · 80 unmodified lines | |||
| 81 | ARM_SMCCC_SMC_32, \ | 81 | ARM_SMCCC_SMC_32, \ |
| 82 | 0, 0x7fff) | 82 | 0, 0x7fff) |
| 83 | 83 | ||
| 84 | /* Paravirtualised time calls (defined by ARM DEN0057A) */ | ||
| 85 | #define ARM_SMCCC_HV_PV_TIME_FEATURES \ | ||
| 86 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | ||
| 87 | ARM_SMCCC_SMC_64, \ | ||
| 88 | ARM_SMCCC_OWNER_STANDARD_HYP, \ | ||
| 89 | 0x20) | ||
| 90 | |||
| 91 | #define ARM_SMCCC_HV_PV_TIME_ST \ | ||
| 92 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | ||
| 93 | ARM_SMCCC_SMC_64, \ | ||
| 94 | ARM_SMCCC_OWNER_STANDARD_HYP, \ | ||
| 95 | 0x21) | ||
| 96 | |||
| 97 | /* | ||
| 98 | * Return codes defined in ARM DEN 0070A | ||
| 99 | * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C | ||
| 100 | */ | ||
| 101 | #define SMCCC_RET_SUCCESS 0 | ||
| 102 | #define SMCCC_RET_NOT_SUPPORTED -1 | ||
| 103 | #define SMCCC_RET_NOT_REQUIRED -2 | ||
| 104 | #define SMCCC_RET_INVALID_PARAMETER -3 | ||
| 105 | |||
| 84 | #ifndef __ASSEMBLY__ | 106 | #ifndef __ASSEMBLY__ |
| 85 | 107 | ||
| 86 | #include <linux/linkage.h> | 108 | #include <linux/linkage.h> |
| @@ -331,15 +353,6 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, · 244 unmodified lines | |||
| 331 | */ | 353 | */ |
| 332 | #define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__) | 354 | #define arm_smccc_1_1_hvc(...) __arm_smccc_1_1(SMCCC_HVC_INST, __VA_ARGS__) |
| 333 | 355 | ||
| 334 | /* | ||
| 335 | * Return codes defined in ARM DEN 0070A | ||
| 336 | * ARM DEN 0070A is now merged/consolidated into ARM DEN 0028 C | ||
| 337 | */ | ||
| 338 | #define SMCCC_RET_SUCCESS 0 | ||
| 339 | #define SMCCC_RET_NOT_SUPPORTED -1 | ||
| 340 | #define SMCCC_RET_NOT_REQUIRED -2 | ||
| 341 | #define SMCCC_RET_INVALID_PARAMETER -3 | ||
| 342 | |||
| 343 | /* | 356 | /* |
| 344 | * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED. | 357 | * Like arm_smccc_1_1* but always returns SMCCC_RET_NOT_SUPPORTED. |
| 345 | * Used when the SMCCC conduit is not defined. The empty asm statement | 358 | * Used when the SMCCC conduit is not defined. The empty asm statement |
| @@ -385,18 +398,5 @@ asmlinkage void __arm_smccc_hvc(unsigned long a0, unsigned long a1, · 39 unmodified lines | |||
| 385 | method; \ | 398 | method; \ |
| 386 | }) | 399 | }) |
| 387 | 400 | ||
| 388 | /* Paravirtualised time calls (defined by ARM DEN0057A) */ | ||
| 389 | #define ARM_SMCCC_HV_PV_TIME_FEATURES \ | ||
| 390 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | ||
| 391 | ARM_SMCCC_SMC_64, \ | ||
| 392 | ARM_SMCCC_OWNER_STANDARD_HYP, \ | ||
| 393 | 0x20) | ||
| 394 | |||
| 395 | #define ARM_SMCCC_HV_PV_TIME_ST \ | ||
| 396 | ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ | ||
| 397 | ARM_SMCCC_SMC_64, \ | ||
| 398 | ARM_SMCCC_OWNER_STANDARD_HYP, \ | ||
| 399 | 0x21) | ||
| 400 | |||
| 401 | #endif /*__ASSEMBLY__*/ | 401 | #endif /*__ASSEMBLY__*/ |
| 402 | #endif /*__LINUX_ARM_SMCCC_H*/ | 402 | #endif /*__LINUX_ARM_SMCCC_H*/ |
| @@ -230,28 +230,6 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, · 229 unmodified lines | |||
| 230 | # define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__) | 230 | # define __UNIQUE_ID(prefix) __PASTE(__PASTE(__UNIQUE_ID_, prefix), __LINE__) |
| 231 | #endif | 231 | #endif |
| 232 | 232 | ||
| 233 | /* | ||
| 234 | * Prevent the compiler from merging or refetching reads or writes. The | ||
| 235 | * compiler is also forbidden from reordering successive instances of | ||
| 236 | * READ_ONCE and WRITE_ONCE, but only when the compiler is aware of some | ||
| 237 | * particular ordering. One way to make the compiler aware of ordering is to | ||
| 238 | * put the two invocations of READ_ONCE or WRITE_ONCE in different C | ||
| 239 | * statements. | ||
| 240 | * | ||
| 241 | * These two macros will also work on aggregate data types like structs or | ||
| 242 | * unions. | ||
| 243 | * | ||
| 244 | * Their two major use cases are: (1) Mediating communication between | ||
| 245 | * process-level code and irq/NMI handlers, all running on the same CPU, | ||
| 246 | * and (2) Ensuring that the compiler does not fold, spindle, or otherwise | ||
| 247 | * mutilate accesses that either do not require ordering or that interact | ||
| 248 | * with an explicit memory barrier or atomic instruction that provides the | ||
| 249 | * required ordering. | ||
| 250 | */ | ||
| 251 | #include <asm/barrier.h> | ||
| 252 | #include <linux/kasan-checks.h> | ||
| 253 | #include <linux/kcsan-checks.h> | ||
| 254 | |||
| 255 | /** | 233 | /** |
| 256 | * data_race - mark an expression as containing intentional data races | 234 | * data_race - mark an expression as containing intentional data races |
| 257 | * | 235 | * |
| @@ -272,65 +250,6 @@ void ftrace_likely_update(struct ftrace_likely_data *f, int val, · 14 unmodified lines | |||
| 272 | __v; \ | 250 | __v; \ |
| 273 | }) | 251 | }) |
| 274 | 252 | ||
| 275 | /* | ||
| 276 | * Use __READ_ONCE() instead of READ_ONCE() if you do not require any | ||
| 277 | * atomicity or dependency ordering guarantees. Note that this may result | ||
| 278 | * in tears! | ||
| 279 | */ | ||
| 280 | #define __READ_ONCE(x) (*(const volatile __unqual_scalar_typeof(x) *)&(x)) | ||
| 281 | |||
| 282 | #define __READ_ONCE_SCALAR(x) \ | ||
| 283 | ({ \ | ||
| 284 | __unqual_scalar_typeof(x) __x = __READ_ONCE(x); \ | ||
| 285 | smp_read_barrier_depends(); \ | ||
| 286 | (typeof(x))__x; \ | ||
| 287 | }) | ||
| 288 | |||
| 289 | #define READ_ONCE(x) \ | ||
| 290 | ({ \ | ||
| 291 | compiletime_assert_rwonce_type(x); \ | ||
| 292 | __READ_ONCE_SCALAR(x); \ | ||
| 293 | }) | ||
| 294 | |||
| 295 | #define __WRITE_ONCE(x, val) \ | ||
| 296 | do { \ | ||
| 297 | *(volatile typeof(x) *)&(x) = (val); \ | ||
| 298 | } while (0) | ||
| 299 | |||
| 300 | #define WRITE_ONCE(x, val) \ | ||
| 301 | do { \ | ||
| 302 | compiletime_assert_rwonce_type(x); \ | ||
| 303 | __WRITE_ONCE(x, val); \ | ||
| 304 | } while (0) | ||
| 305 | |||
| 306 | static __no_sanitize_or_inline | ||
| 307 | unsigned long __read_once_word_nocheck(const void *addr) | ||
| 308 | { | ||
| 309 | return __READ_ONCE(*(unsigned long *)addr); | ||
| 310 | } | ||
| 311 | |||
| 312 | /* | ||
| 313 | * Use READ_ONCE_NOCHECK() instead of READ_ONCE() if you need to load a | ||
| 314 | * word from memory atomically but without telling KASAN/KCSAN. This is | ||
| 315 | * usually used by unwinding code when walking the stack of a running process. | ||
| 316 | */ | ||
| 317 | #define READ_ONCE_NOCHECK(x) \ | ||
| 318 | ({ \ | ||
| 319 | unsigned long __x; \ | ||
| 320 | compiletime_assert(sizeof(x) == sizeof(__x), \ | ||
| 321 | "Unsupported access size for READ_ONCE_NOCHECK()."); \ | ||
| 322 | __x = __read_once_word_nocheck(&(x)); \ | ||
| 323 | smp_read_barrier_depends(); \ | ||
| 324 | (typeof(x))__x; \ | ||
| 325 | }) | ||
| 326 | |||
| 327 | static __no_kasan_or_inline | ||
| 328 | unsigned long read_word_at_a_time(const void *addr) | ||
| 329 | { | ||
| 330 | kasan_check_read(addr, 1); | ||
| 331 | return *(unsigned long *)addr; | ||
| 332 | } | ||
| 333 | |||
| 334 | #endif /* __KERNEL__ */ | 253 | #endif /* __KERNEL__ */ |
| 335 | 254 | ||
| 336 | /* | 255 | /* |
| @@ -354,57 +273,6 @@ static inline void *offset_to_ptr(const int *off) · 17 unmodified lines | |||
| 354 | 273 | ||
| 355 | #endif /* __ASSEMBLY__ */ | 274 | #endif /* __ASSEMBLY__ */ |
| 356 | 275 | ||
| 357 | /* Compile time object size, -1 for unknown */ | ||
| 358 | #ifndef __compiletime_object_size | ||
| 359 | # define __compiletime_object_size(obj) -1 | ||
| 360 | #endif | ||
| 361 | #ifndef __compiletime_warning | ||
| 362 | # define __compiletime_warning(message) | ||
| 363 | #endif | ||
| 364 | #ifndef __compiletime_error | ||
| 365 | # define __compiletime_error(message) | ||
| 366 | #endif | ||
| 367 | |||
| 368 | #ifdef __OPTIMIZE__ | ||
| 369 | # define __compiletime_assert(condition, msg, prefix, suffix) \ | ||
| 370 | do { \ | ||
| 371 | extern void prefix ## suffix(void) __compiletime_error(msg); \ | ||
| 372 | if (!(condition)) \ | ||
| 373 | prefix ## suffix(); \ | ||
| 374 | } while (0) | ||
| 375 | #else | ||
| 376 | # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0) | ||
| 377 | #endif | ||
| 378 | |||
| 379 | #define _compiletime_assert(condition, msg, prefix, suffix) \ | ||
| 380 | __compiletime_assert(condition, msg, prefix, suffix) | ||
| 381 | |||
| 382 | /** | ||
| 383 | * compiletime_assert - break build and emit msg if condition is false | ||
| 384 | * @condition: a compile-time constant condition to check | ||
| 385 | * @msg: a message to emit if condition is false | ||
| 386 | * | ||
| 387 | * In tradition of POSIX assert, this macro will break the build if the | ||
| 388 | * supplied condition is *false*, emitting the supplied error message if the | ||
| 389 | * compiler has support to do so. | ||
| 390 | */ | ||
| 391 | #define compiletime_assert(condition, msg) \ | ||
| 392 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ||
| 393 | |||
| 394 | #define compiletime_assert_atomic_type(t) \ | ||
| 395 | compiletime_assert(__native_word(t), \ | ||
| 396 | "Need native word sized stores/loads for atomicity.") | ||
| 397 | |||
| 398 | /* | ||
| 399 | * Yes, this permits 64-bit accesses on 32-bit architectures. These will | ||
| 400 | * actually be atomic in some cases (namely Armv7 + LPAE), but for others we | ||
| 401 | * rely on the access being split into 2x32-bit accesses for a 32-bit quantity | ||
| 402 | * (e.g. a virtual address) and a strong prevailing wind. | ||
| 403 | */ | ||
| 404 | #define compiletime_assert_rwonce_type(t) \ | ||
| 405 | compiletime_assert(__native_word(t) || sizeof(t) == sizeof(long long), \ | ||
| 406 | "Unsupported access size for {READ,WRITE}_ONCE().") | ||
| 407 | |||
| 408 | /* &a[0] degrades to a pointer: a different type from an array */ | 276 | /* &a[0] degrades to a pointer: a different type from an array */ |
| 409 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) | 277 | #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0])) |
| 410 | 278 | ||
| @@ -414,4 +282,6 @@ static inline void *offset_to_ptr(const int *off) · 3 unmodified lines | |||
| 414 | */ | 282 | */ |
| 415 | #define prevent_tail_call_optimization() mb() | 283 | #define prevent_tail_call_optimization() mb() |
| 416 | 284 | ||
| 285 | #include <asm/rwonce.h> | ||
| 286 | |||
| 417 | #endif /* __LINUX_COMPILER_H */ | 287 | #endif /* __LINUX_COMPILER_H */ |
| @@ -275,6 +275,47 @@ struct ftrace_likely_data { · 274 unmodified lines | |||
| 275 | (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \ | 275 | (sizeof(t) == sizeof(char) || sizeof(t) == sizeof(short) || \ |
| 276 | sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) | 276 | sizeof(t) == sizeof(int) || sizeof(t) == sizeof(long)) |
| 277 | 277 | ||
| 278 | /* Compile time object size, -1 for unknown */ | ||
| 279 | #ifndef __compiletime_object_size | ||
| 280 | # define __compiletime_object_size(obj) -1 | ||
| 281 | #endif | ||
| 282 | #ifndef __compiletime_warning | ||
| 283 | # define __compiletime_warning(message) | ||
| 284 | #endif | ||
| 285 | #ifndef __compiletime_error | ||
| 286 | # define __compiletime_error(message) | ||
| 287 | #endif | ||
| 288 | |||
| 289 | #ifdef __OPTIMIZE__ | ||
| 290 | # define __compiletime_assert(condition, msg, prefix, suffix) \ | ||
| 291 | do { \ | ||
| 292 | extern void prefix ## suffix(void) __compiletime_error(msg); \ | ||
| 293 | if (!(condition)) \ | ||
| 294 | prefix ## suffix(); \ | ||
| 295 | } while (0) | ||
| 296 | #else | ||
| 297 | # define __compiletime_assert(condition, msg, prefix, suffix) do { } while (0) | ||
| 298 | #endif | ||
| 299 | |||
| 300 | #define _compiletime_assert(condition, msg, prefix, suffix) \ | ||
| 301 | __compiletime_assert(condition, msg, prefix, suffix) | ||
| 302 | |||
| 303 | /** | ||
| 304 | * compiletime_assert - break build and emit msg if condition is false | ||
| 305 | * @condition: a compile-time constant condition to check | ||
| 306 | * @msg: a message to emit if condition is false | ||
| 307 | * | ||
| 308 | * In tradition of POSIX assert, this macro will break the build if the | ||
| 309 | * supplied condition is *false*, emitting the supplied error message if the | ||
| 310 | * compiler has support to do so. | ||
| 311 | */ | ||
| 312 | #define compiletime_assert(condition, msg) \ | ||
| 313 | _compiletime_assert(condition, msg, __compiletime_assert_, __COUNTER__) | ||
| 314 | |||
| 315 | #define compiletime_assert_atomic_type(t) \ | ||
| 316 | compiletime_assert(__native_word(t), \ | ||
| 317 | "Need native word sized stores/loads for atomicity.") | ||
| 318 | |||
| 278 | /* Helpers for emitting diagnostics in pragmas. */ | 319 | /* Helpers for emitting diagnostics in pragmas. */ |
| 279 | #ifndef __diag | 320 | #ifndef __diag |
| 280 | #define __diag(string) | 321 | #define __diag(string) |
| @@ -5,6 +5,8 @@ · 4 unmodified lines | |||
| 5 | 5 | ||
| 6 | #ifndef _LINUX_NOSPEC_H | 6 | #ifndef _LINUX_NOSPEC_H |
| 7 | #define _LINUX_NOSPEC_H | 7 | #define _LINUX_NOSPEC_H |
| 8 | |||
| 9 | #include <linux/compiler.h> | ||
| 8 | #include <asm/barrier.h> | 10 | #include <asm/barrier.h> |
| 9 | 11 | ||
| 10 | struct task_struct; | 12 | struct task_struct; |
| @@ -554,7 +554,7 @@ bool of_console_check(struct device_node *dn, char *name, int index); · 553 unmodified lines | |||
| 554 | 554 | ||
| 555 | extern int of_cpu_node_to_id(struct device_node *np); | 555 | extern int of_cpu_node_to_id(struct device_node *np); |
| 556 | 556 | ||
| 557 | int of_map_rid(struct device_node *np, u32 rid, | 557 | int of_map_id(struct device_node *np, u32 id, |
| 558 | const char *map_name, const char *map_mask_name, | 558 | const char *map_name, const char *map_mask_name, |
| 559 | struct device_node **target, u32 *id_out); | 559 | struct device_node **target, u32 *id_out); |
| 560 | 560 | ||
| @@ -978,7 +978,7 @@ static inline int of_cpu_node_to_id(struct device_node *np) · 417 unmodified lines | |||
| 978 | return -ENODEV; | 978 | return -ENODEV; |
| 979 | } | 979 | } |
| 980 | 980 | ||
| 981 | static inline int of_map_rid(struct device_node *np, u32 rid, | 981 | static inline int of_map_id(struct device_node *np, u32 id, |
| 982 | const char *map_name, const char *map_mask_name, | 982 | const char *map_name, const char *map_mask_name, |
| 983 | struct device_node **target, u32 *id_out) | 983 | struct device_node **target, u32 *id_out) |
| 984 | { | 984 | { |
| @@ -55,9 +55,15 @@ static inline struct device_node *of_cpu_device_node_get(int cpu) · 54 unmodified lines | |||
| 55 | return of_node_get(cpu_dev->of_node); | 55 | return of_node_get(cpu_dev->of_node); |
| 56 | } | 56 | } |
| 57 | 57 | ||
| 58 | int of_dma_configure(struct device *dev, | 58 | int of_dma_configure_id(struct device *dev, |
| 59 | struct device_node *np, | 59 | struct device_node *np, |
| 60 | bool force_dma); | 60 | bool force_dma, const u32 *id); |
| 61 | static inline int of_dma_configure(struct device *dev, | ||
| 62 | struct device_node *np, | ||
| 63 | bool force_dma) | ||
| 64 | { | ||
| 65 | return of_dma_configure_id(dev, np, force_dma, NULL); | ||
| 66 | } | ||
| 61 | #else /* CONFIG_OF */ | 67 | #else /* CONFIG_OF */ |
| 62 | 68 | ||
| 63 | static inline int of_driver_match_device(struct device *dev, | 69 | static inline int of_driver_match_device(struct device *dev, |
| @@ -106,6 +112,12 @@ static inline struct device_node *of_cpu_device_node_get(int cpu) · 42 unmodified lines | |||
| 106 | return NULL; | 112 | return NULL; |
| 107 | } | 113 | } |
| 108 | 114 | ||
| 115 | static inline int of_dma_configure_id(struct device *dev, | ||
| 116 | struct device_node *np, | ||
| 117 | bool force_dma) | ||
| 118 | { | ||
| 119 | return 0; | ||
| 120 | } | ||
| 109 | static inline int of_dma_configure(struct device *dev, | 121 | static inline int of_dma_configure(struct device *dev, |
| 110 | struct device_node *np, | 122 | struct device_node *np, |
| 111 | bool force_dma) | 123 | bool force_dma) |
| @@ -13,7 +13,8 @@ extern int of_get_dma_window(struct device_node *dn, const char *prefix, · 12 unmodified lines | |||
| 13 | size_t *size); | 13 | size_t *size); |
| 14 | 14 | ||
| 15 | extern const struct iommu_ops *of_iommu_configure(struct device *dev, | 15 | extern const struct iommu_ops *of_iommu_configure(struct device *dev, |
| 16 | struct device_node *master_np); | 16 | struct device_node *master_np, |
| 17 | const u32 *id); | ||
| 17 | 18 | ||
| 18 | #else | 19 | #else |
| 19 | 20 | ||
| @@ -25,7 +26,8 @@ static inline int of_get_dma_window(struct device_node *dn, const char *prefix, · 5 unmodified lines | |||
| 25 | } | 26 | } |
| 26 | 27 | ||
| 27 | static inline const struct iommu_ops *of_iommu_configure(struct device *dev, | 28 | static inline const struct iommu_ops *of_iommu_configure(struct device *dev, |
| 28 | struct device_node *master_np) | 29 | struct device_node *master_np, |
| 30 | const u32 *id) | ||
| 29 | { | 31 | { |
| 30 | return NULL; | 32 | return NULL; |
| 31 | } | 33 | } |
| @@ -52,9 +52,10 @@ extern struct irq_domain *of_msi_get_domain(struct device *dev, · 51 unmodified lines | |||
| 52 | struct device_node *np, | 52 | struct device_node *np, |
| 53 | enum irq_domain_bus_token token); | 53 | enum irq_domain_bus_token token); |
| 54 | extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev, | 54 | extern struct irq_domain *of_msi_map_get_device_domain(struct device *dev, |
| 55 | u32 rid); | 55 | u32 id, |
| 56 | u32 bus_token); | ||
| 56 | extern void of_msi_configure(struct device *dev, struct device_node *np); | 57 | extern void of_msi_configure(struct device *dev, struct device_node *np); |
| 57 | u32 of_msi_map_rid(struct device *dev, struct device_node *msi_np, u32 rid_in); | 58 | u32 of_msi_map_id(struct device *dev, struct device_node *msi_np, u32 id_in); |
| 58 | #else | 59 | #else |
| 59 | static inline int of_irq_count(struct device_node *dev) | 60 | static inline int of_irq_count(struct device_node *dev) |
| 60 | { | 61 | { |
| @@ -85,17 +86,17 @@ static inline struct irq_domain *of_msi_get_domain(struct device *dev, · 24 unmodified lines | |||
| 85 | return NULL; | 86 | return NULL; |
| 86 | } | 87 | } |
| 87 | static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev, | 88 | static inline struct irq_domain *of_msi_map_get_device_domain(struct device *dev, |
| 88 | u32 rid) | 89 | u32 id, u32 bus_token) |
| 89 | { | 90 | { |
| 90 | return NULL; | 91 | return NULL; |
| 91 | } | 92 | } |
| 92 | static inline void of_msi_configure(struct device *dev, struct device_node *np) | 93 | static inline void of_msi_configure(struct device *dev, struct device_node *np) |
| 93 | { | 94 | { |
| 94 | } | 95 | } |
| 95 | static inline u32 of_msi_map_rid(struct device *dev, | 96 | static inline u32 of_msi_map_id(struct device *dev, |
| 96 | struct device_node *msi_np, u32 rid_in) | 97 | struct device_node *msi_np, u32 id_in) |
| 97 | { | 98 | { |
| 98 | return rid_in; | 99 | return id_in; |
| 99 | } | 100 | } |
| 100 | #endif | 101 | #endif |
| 101 | 102 | ||
| @@ -155,7 +155,7 @@ static inline bool __ref_is_percpu(struct percpu_ref *ref, · 154 unmodified lines | |||
| 155 | * between contaminating the pointer value, meaning that | 155 | * between contaminating the pointer value, meaning that |
| 156 | * READ_ONCE() is required when fetching it. | 156 | * READ_ONCE() is required when fetching it. |
| 157 | * | 157 | * |
| 158 | * The smp_read_barrier_depends() implied by READ_ONCE() pairs | 158 | * The dependency ordering from the READ_ONCE() pairs |
| 159 | * with smp_store_release() in __percpu_ref_switch_to_percpu(). | 159 | * with smp_store_release() in __percpu_ref_switch_to_percpu(). |
| 160 | */ | 160 | */ |
| 161 | percpu_ptr = READ_ONCE(ref->percpu_count_ptr); | 161 | percpu_ptr = READ_ONCE(ref->percpu_count_ptr); |
| @@ -107,7 +107,7 @@ static inline int __ptr_ring_produce(struct ptr_ring *r, void *ptr) · 106 unmodified lines | |||
| 107 | return -ENOSPC; | 107 | return -ENOSPC; |
| 108 | 108 | ||
| 109 | /* Make sure the pointer we are storing points to a valid data. */ | 109 | /* Make sure the pointer we are storing points to a valid data. */ |
| 110 | /* Pairs with smp_read_barrier_depends in __ptr_ring_consume. */ | 110 | /* Pairs with the dependency ordering in __ptr_ring_consume. */ |
| 111 | smp_wmb(); | 111 | smp_wmb(); |
| 112 | 112 | ||
| 113 | WRITE_ONCE(r->queue[r->producer++], ptr); | 113 | WRITE_ONCE(r->queue[r->producer++], ptr); |
| @@ -6,6 +6,34 @@ · 5 unmodified lines | |||
| 6 | #define LINUX_SCHED_CLOCK | 6 | #define LINUX_SCHED_CLOCK |
| 7 | 7 | ||
| 8 | #ifdef CONFIG_GENERIC_SCHED_CLOCK | 8 | #ifdef CONFIG_GENERIC_SCHED_CLOCK |
| 9 | /** | ||
| 10 | * struct clock_read_data - data required to read from sched_clock() | ||
| 11 | * | ||
| 12 | * @epoch_ns: sched_clock() value at last update | ||
| 13 | * @epoch_cyc: Clock cycle value at last update. | ||
| 14 | * @sched_clock_mask: Bitmask for two's complement subtraction of non 64bit | ||
| 15 | * clocks. | ||
| 16 | * @read_sched_clock: Current clock source (or dummy source when suspended). | ||
| 17 | * @mult: Multipler for scaled math conversion. | ||
| 18 | * @shift: Shift value for scaled math conversion. | ||
| 19 | * | ||
| 20 | * Care must be taken when updating this structure; it is read by | ||
| 21 | * some very hot code paths. It occupies <=40 bytes and, when combined | ||
| 22 | * with the seqcount used to synchronize access, comfortably fits into | ||
| 23 | * a 64 byte cache line. | ||
| 24 | */ | ||
| 25 | struct clock_read_data { | ||
| 26 | u64 epoch_ns; | ||
| 27 | u64 epoch_cyc; | ||
| 28 | u64 sched_clock_mask; | ||
| 29 | u64 (*read_sched_clock)(void); | ||
| 30 | u32 mult; | ||
| 31 | u32 shift; | ||
| 32 | }; | ||
| 33 | |||
| 34 | extern struct clock_read_data *sched_clock_read_begin(unsigned int *seq); | ||
| 35 | extern int sched_clock_read_retry(unsigned int seq); | ||
| 36 | |||
| 9 | extern void generic_sched_clock_init(void); | 37 | extern void generic_sched_clock_init(void); |
| 10 | 38 | ||
| 11 | extern void sched_clock_register(u64 (*read)(void), int bits, | 39 | extern void sched_clock_register(u64 (*read)(void), int bits, |
| @@ -532,9 +532,10 @@ struct perf_event_mmap_page { · 531 unmodified lines | |||
| 532 | cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */ | 532 | cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */ |
| 533 | 533 | ||
| 534 | cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */ | 534 | cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */ |
| 535 | cap_user_time : 1, /* The time_* fields are used */ | 535 | cap_user_time : 1, /* The time_{shift,mult,offset} fields are used */ |
| 536 | cap_user_time_zero : 1, /* The time_zero field is used */ | 536 | cap_user_time_zero : 1, /* The time_zero field is used */ |
| 537 | cap_____res : 59; | 537 | cap_user_time_short : 1, /* the time_{cycle,mask} fields are used */ |
| 538 | cap_____res : 58; | ||
| 538 | }; | 539 | }; |
| 539 | }; | 540 | }; |
| 540 | 541 | ||
| @@ -593,13 +594,29 @@ struct perf_event_mmap_page { · 52 unmodified lines | |||
| 593 | * ((rem * time_mult) >> time_shift); | 594 | * ((rem * time_mult) >> time_shift); |
| 594 | */ | 595 | */ |
| 595 | __u64 time_zero; | 596 | __u64 time_zero; |
| 597 | |||
| 596 | __u32 size; /* Header size up to __reserved[] fields. */ | 598 | __u32 size; /* Header size up to __reserved[] fields. */ |
| 599 | __u32 __reserved_1; | ||
| 600 | |||
| 601 | /* | ||
| 602 | * If cap_usr_time_short, the hardware clock is less than 64bit wide | ||
| 603 | * and we must compute the 'cyc' value, as used by cap_usr_time, as: | ||
| 604 | * | ||
| 605 | * cyc = time_cycles + ((cyc - time_cycles) & time_mask) | ||
| 606 | * | ||
| 607 | * NOTE: this form is explicitly chosen such that cap_usr_time_short | ||
| 608 | * is a correction on top of cap_usr_time, and code that doesn't | ||
| 609 | * know about cap_usr_time_short still works under the assumption | ||
| 610 | * the counter doesn't wrap. | ||
| 611 | */ | ||
| 612 | __u64 time_cycles; | ||
| 613 | __u64 time_mask; | ||
| 597 | 614 | ||
| 598 | /* | 615 | /* |
| 599 | * Hole for extension of the self monitor capabilities | 616 | * Hole for extension of the self monitor capabilities |
| 600 | */ | 617 | */ |
| 601 | 618 | ||
| 602 | __u8 __reserved[118*8+4]; /* align to 1k. */ | 619 | __u8 __reserved[116*8]; /* align to 1k. */ |
| 603 | 620 | ||
| 604 | /* | 621 | /* |
| 605 | * Control data for the mmap() data buffer. | 622 | * Control data for the mmap() data buffer. |
| @@ -109,6 +109,7 @@ struct vdso_data { · 108 unmodified lines | |||
| 109 | * relocation, and this is what we need. | 109 | * relocation, and this is what we need. |
| 110 | */ | 110 | */ |
| 111 | extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden"))); | 111 | extern struct vdso_data _vdso_data[CS_BASES] __attribute__((visibility("hidden"))); |
| 112 | extern struct vdso_data _timens_data[CS_BASES] __attribute__((visibility("hidden"))); | ||
| 112 | 113 | ||
| 113 | /* | 114 | /* |
| 114 | * The generic vDSO implementation requires that gettimeofday.h | 115 | * The generic vDSO implementation requires that gettimeofday.h |
| @@ -413,6 +413,7 @@ static int __init crash_save_vmcoreinfo_init(void) · 412 unmodified lines | |||
| 413 | VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS); | 413 | VMCOREINFO_LENGTH(mem_section, NR_SECTION_ROOTS); |
| 414 | VMCOREINFO_STRUCT_SIZE(mem_section); | 414 | VMCOREINFO_STRUCT_SIZE(mem_section); |
| 415 | VMCOREINFO_OFFSET(mem_section, section_mem_map); | 415 | VMCOREINFO_OFFSET(mem_section, section_mem_map); |
| 416 | VMCOREINFO_NUMBER(MAX_PHYSMEM_BITS); | ||
| 416 | #endif | 417 | #endif |
| 417 | VMCOREINFO_STRUCT_SIZE(page); | 418 | VMCOREINFO_STRUCT_SIZE(page); |
| 418 | VMCOREINFO_STRUCT_SIZE(pglist_data); | 419 | VMCOREINFO_STRUCT_SIZE(pglist_data); |
| @@ -19,31 +19,6 @@ · 18 unmodified lines | |||
| 19 | 19 | ||
| 20 | #include "timekeeping.h" | 20 | #include "timekeeping.h" |
| 21 | 21 | ||
| 22 | /** | ||
| 23 | * struct clock_read_data - data required to read from sched_clock() | ||
| 24 | * | ||
| 25 | * @epoch_ns: sched_clock() value at last update | ||
| 26 | * @epoch_cyc: Clock cycle value at last update. | ||
| 27 | * @sched_clock_mask: Bitmask for two's complement subtraction of non 64bit | ||
| 28 | * clocks. | ||
| 29 | * @read_sched_clock: Current clock source (or dummy source when suspended). | ||
| 30 | * @mult: Multipler for scaled math conversion. | ||
| 31 | * @shift: Shift value for scaled math conversion. | ||
| 32 | * | ||
| 33 | * Care must be taken when updating this structure; it is read by | ||
| 34 | * some very hot code paths. It occupies <=40 bytes and, when combined | ||
| 35 | * with the seqcount used to synchronize access, comfortably fits into | ||
| 36 | * a 64 byte cache line. | ||
| 37 | */ | ||
| 38 | struct clock_read_data { | ||
| 39 | u64 epoch_ns; | ||
| 40 | u64 epoch_cyc; | ||
| 41 | u64 sched_clock_mask; | ||
| 42 | u64 (*read_sched_clock)(void); | ||
| 43 | u32 mult; | ||
| 44 | u32 shift; | ||
| 45 | }; | ||
| 46 | |||
| 47 | /** | 22 | /** |
| 48 | * struct clock_data - all data needed for sched_clock() (including | 23 | * struct clock_data - all data needed for sched_clock() (including |
| 49 | * registration of a new clock source) | 24 | * registration of a new clock source) |
| @@ -93,6 +68,17 @@ static inline u64 notrace cyc_to_ns(u64 cyc, u32 mult, u32 shift) · 43 unmodified lines | |||
| 93 | return (cyc * mult) >> shift; | 68 | return (cyc * mult) >> shift; |
| 94 | } | 69 | } |
| 95 | 70 | ||
| 71 | struct clock_read_data *sched_clock_read_begin(unsigned int *seq) | ||
| 72 | { | ||
| 73 | *seq = raw_read_seqcount_latch(&cd.seq); | ||
| 74 | return cd.read_data + (*seq & 1); | ||
| 75 | } | ||
| 76 | |||
| 77 | int sched_clock_read_retry(unsigned int seq) | ||
| 78 | { | ||
| 79 | return read_seqcount_retry(&cd.seq, seq); | ||
| 80 | } | ||
| 81 | |||
| 96 | unsigned long long notrace sched_clock(void) | 82 | unsigned long long notrace sched_clock(void) |
| 97 | { | 83 | { |
| 98 | u64 cyc, res; | 84 | u64 cyc, res; |
| @@ -100,13 +86,12 @@ unsigned long long notrace sched_clock(void) · 1 unmodified line | |||
| 100 | struct clock_read_data *rd; | 86 | struct clock_read_data *rd; |
| 101 | 87 | ||
| 102 | do { | 88 | do { |
| 103 | seq = raw_read_seqcount(&cd.seq); | 89 | rd = sched_clock_read_begin(&seq); |
| 104 | rd = cd.read_data + (seq & 1); | ||
| 105 | 90 | ||
| 106 | cyc = (rd->read_sched_clock() - rd->epoch_cyc) & | 91 | cyc = (rd->read_sched_clock() - rd->epoch_cyc) & |
| 107 | rd->sched_clock_mask; | 92 | rd->sched_clock_mask; |
| 108 | res = rd->epoch_ns + cyc_to_ns(cyc, rd->mult, rd->shift); | 93 | res = rd->epoch_ns + cyc_to_ns(cyc, rd->mult, rd->shift); |
| 109 | } while (read_seqcount_retry(&cd.seq, seq)); | 94 | } while (sched_clock_read_retry(seq)); |
| 110 | 95 | ||
| 111 | return res; | 96 | return res; |
| 112 | } | 97 | } |
| @@ -437,7 +437,7 @@ int __pte_alloc(struct mm_struct *mm, pmd_t *pmd) · 436 unmodified lines | |||
| 437 | * of a chain of data-dependent loads, meaning most CPUs (alpha | 437 | * of a chain of data-dependent loads, meaning most CPUs (alpha |
| 438 | * being the notable exception) will already guarantee loads are | 438 | * being the notable exception) will already guarantee loads are |
| 439 | * seen in-order. See the alpha page table accessors for the | 439 | * seen in-order. See the alpha page table accessors for the |
| 440 | * smp_read_barrier_depends() barriers in page table walking code. | 440 | * smp_rmb() barriers in page table walking code. |
| 441 | */ | 441 | */ |
| 442 | smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */ | 442 | smp_wmb(); /* Could be smp_wmb__xxx(before|after)_spin_lock */ |
| 443 | 443 | ||
| @@ -5903,8 +5903,7 @@ sub process { · 5902 unmodified lines | |||
| 5903 | my $barriers = qr{ | 5903 | my $barriers = qr{ |
| 5904 | mb| | 5904 | mb| |
| 5905 | rmb| | 5905 | rmb| |
| 5906 | wmb| | 5906 | wmb |
| 5907 | read_barrier_depends | ||
| 5908 | }x; | 5907 | }x; |
| 5909 | my $barrier_stems = qr{ | 5908 | my $barrier_stems = qr{ |
| 5910 | mb__before_atomic| | 5909 | mb__before_atomic| |
| @@ -5953,12 +5952,6 @@ sub process { · 42 unmodified lines | |||
| 5953 | } | 5952 | } |
| 5954 | } | 5953 | } |
| 5955 | 5954 | ||
| 5956 | # check for smp_read_barrier_depends and read_barrier_depends | ||
| 5957 | if (!$file && $line =~ /\b(smp_|)read_barrier_depends\s*\(/) { | ||
| 5958 | WARN("READ_BARRIER_DEPENDS", | ||
| 5959 | "$1read_barrier_depends should only be used in READ_ONCE or DEC Alpha code\n" . $herecurr); | ||
| 5960 | } | ||
| 5961 | |||
| 5962 | # check of hardware specific defines | 5955 | # check of hardware specific defines |
| 5963 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { | 5956 | if ($line =~ m@^.\s*\#\s*if.*\b(__i386__|__powerpc64__|__sun__|__s390x__)\b@ && $realfile !~ m@include/asm-@) { |
| 5964 | CHK("ARCH_DEFINES", | 5957 | CHK("ARCH_DEFINES", |
| @@ -434,6 +434,11 @@ static int arm_is_fake_mcount(Elf32_Rel const *rp) · 433 unmodified lines | |||
| 434 | return 1; | 434 | return 1; |
| 435 | } | 435 | } |
| 436 | 436 | ||
| 437 | static int arm64_is_fake_mcount(Elf64_Rel const *rp) | ||
| 438 | { | ||
| 439 | return ELF64_R_TYPE(w(rp->r_info)) != R_AARCH64_CALL26; | ||
| 440 | } | ||
| 441 | |||
| 437 | /* 64-bit EM_MIPS has weird ELF64_Rela.r_info. | 442 | /* 64-bit EM_MIPS has weird ELF64_Rela.r_info. |
| 438 | * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf | 443 | * http://techpubs.sgi.com/library/manuals/4000/007-4658-001/pdf/007-4658-001.pdf |
| 439 | * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40] | 444 | * We interpret Table 29 Relocation Operation (Elf64_Rel, Elf64_Rela) [p.40] |
| @@ -547,6 +552,7 @@ static int do_file(char const *const fname) · 107 unmodified lines | |||
| 547 | make_nop = make_nop_arm64; | 552 | make_nop = make_nop_arm64; |
| 548 | rel_type_nop = R_AARCH64_NONE; | 553 | rel_type_nop = R_AARCH64_NONE; |
| 549 | ideal_nop = ideal_nop4_arm64; | 554 | ideal_nop = ideal_nop4_arm64; |
| 555 | is_fake_mcount64 = arm64_is_fake_mcount; | ||
| 550 | break; | 556 | break; |
| 551 | case EM_IA_64: reltype = R_IA64_IMM64; break; | 557 | case EM_IA_64: reltype = R_IA64_IMM64; break; |
| 552 | case EM_MIPS: /* reltype: e_class */ break; | 558 | case EM_MIPS: /* reltype: e_class */ break; |
| @@ -9,7 +9,8 @@ MAKE = make · 8 unmodified lines | |||
| 9 | INSTALL ?= install | 9 | INSTALL ?= install |
| 10 | 10 | ||
| 11 | CFLAGS += -Wall -O2 | 11 | CFLAGS += -Wall -O2 |
| 12 | CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/include/uapi -I$(srctree)/include | 12 | CFLAGS += -D__EXPORTED_HEADERS__ -I$(srctree)/tools/include/uapi \ |
| 13 | -I$(srctree)/tools/include | ||
| 13 | 14 | ||
| 14 | # This will work when bpf is built in tools env. where srctree | 15 | # This will work when bpf is built in tools env. where srctree |
| 15 | # isn't set and when invoked from selftests build, where srctree | 16 | # isn't set and when invoked from selftests build, where srctree |
| @@ -0,0 +1,90 @@ | |||
| 1 | /* SPDX-License-Identifier: GPL-2.0 WITH Linux-syscall-note */ | ||
| 2 | /* | ||
| 3 | * Linux Socket Filter Data Structures | ||
| 4 | */ | ||
| 5 | |||
| 6 | #ifndef __LINUX_FILTER_H__ | ||
| 7 | #define __LINUX_FILTER_H__ | ||
| 8 | |||
| 9 | |||
| 10 | #include <linux/types.h> | ||
| 11 | #include <linux/bpf_common.h> | ||
| 12 | |||
| 13 | /* | ||
| 14 | * Current version of the filter code architecture. | ||
| 15 | */ | ||
| 16 | #define BPF_MAJOR_VERSION 1 | ||
| 17 | #define BPF_MINOR_VERSION 1 | ||
| 18 | |||
| 19 | /* | ||
| 20 | * Try and keep these values and structures similar to BSD, especially | ||
| 21 | * the BPF code definitions which need to match so you can share filters | ||
| 22 | */ | ||
| 23 | |||
| 24 | struct sock_filter { /* Filter block */ | ||
| 25 | __u16 code; /* Actual filter code */ | ||
| 26 | __u8 jt; /* Jump true */ | ||
| 27 | __u8 jf; /* Jump false */ | ||
| 28 | __u32 k; /* Generic multiuse field */ | ||
| 29 | }; | ||
| 30 | |||
| 31 | struct sock_fprog { /* Required for SO_ATTACH_FILTER. */ | ||
| 32 | unsigned short len; /* Number of filter blocks */ | ||
| 33 | struct sock_filter *filter; | ||
| 34 | }; | ||
| 35 | |||
| 36 | /* ret - BPF_K and BPF_X also apply */ | ||
| 37 | #define BPF_RVAL(code) ((code) & 0x18) | ||
| 38 | #define BPF_A 0x10 | ||
| 39 | |||
| 40 | /* misc */ | ||
| 41 | #define BPF_MISCOP(code) ((code) & 0xf8) | ||
| 42 | #define BPF_TAX 0x00 | ||
| 43 | #define BPF_TXA 0x80 | ||
| 44 | |||
| 45 | /* | ||
| 46 | * Macros for filter block array initializers. | ||
| 47 | */ | ||
| 48 | #ifndef BPF_STMT | ||
| 49 | #define BPF_STMT(code, k) { (unsigned short)(code), 0, 0, k } | ||
| 50 | #endif | ||
| 51 | #ifndef BPF_JUMP | ||
| 52 | #define BPF_JUMP(code, k, jt, jf) { (unsigned short)(code), jt, jf, k } | ||
| 53 | #endif | ||
| 54 | |||
| 55 | /* | ||
| 56 | * Number of scratch memory words for: BPF_ST and BPF_STX | ||
| 57 | */ | ||
| 58 | #define BPF_MEMWORDS 16 | ||
| 59 | |||
| 60 | /* RATIONALE. Negative offsets are invalid in BPF. | ||
| 61 | We use them to reference ancillary data. | ||
| 62 | Unlike introduction new instructions, it does not break | ||
| 63 | existing compilers/optimizers. | ||
| 64 | */ | ||
| 65 | #define SKF_AD_OFF (-0x1000) | ||
| 66 | #define SKF_AD_PROTOCOL 0 | ||
| 67 | #define SKF_AD_PKTTYPE 4 | ||
| 68 | #define SKF_AD_IFINDEX 8 | ||
| 69 | #define SKF_AD_NLATTR 12 | ||
| 70 | #define SKF_AD_NLATTR_NEST 16 | ||
| 71 | #define SKF_AD_MARK 20 | ||
| 72 | #define SKF_AD_QUEUE 24 | ||
| 73 | #define SKF_AD_HATYPE 28 | ||
| 74 | #define SKF_AD_RXHASH 32 | ||
| 75 | #define SKF_AD_CPU 36 | ||
| 76 | #define SKF_AD_ALU_XOR_X 40 | ||
| 77 | #define SKF_AD_VLAN_TAG 44 | ||
| 78 | #define SKF_AD_VLAN_TAG_PRESENT 48 | ||
| 79 | #define SKF_AD_PAY_OFFSET 52 | ||
| 80 | #define SKF_AD_RANDOM 56 | ||
| 81 | #define SKF_AD_VLAN_TPID 60 | ||
| 82 | #define SKF_AD_MAX 64 | ||
| 83 | |||
| 84 | #define SKF_NET_OFF (-0x100000) | ||
| 85 | #define SKF_LL_OFF (-0x200000) | ||
| 86 | |||
| 87 | #define BPF_NET_OFF SKF_NET_OFF | ||
| 88 | #define BPF_LL_OFF SKF_LL_OFF | ||
| 89 | |||
| 90 | #endif /* __LINUX_FILTER_H__ */ | ||
| @@ -532,9 +532,10 @@ struct perf_event_mmap_page { · 531 unmodified lines | |||
| 532 | cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */ | 532 | cap_bit0_is_deprecated : 1, /* Always 1, signals that bit 0 is zero */ |
| 533 | 533 | ||
| 534 | cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */ | 534 | cap_user_rdpmc : 1, /* The RDPMC instruction can be used to read counts */ |
| 535 | cap_user_time : 1, /* The time_* fields are used */ | 535 | cap_user_time : 1, /* The time_{shift,mult,offset} fields are used */ |
| 536 | cap_user_time_zero : 1, /* The time_zero field is used */ | 536 | cap_user_time_zero : 1, /* The time_zero field is used */ |
| 537 | cap_____res : 59; | 537 | cap_user_time_short : 1, /* the time_{cycle,mask} fields are used */ |
| 538 | cap_____res : 58; | ||
| 538 | }; | 539 | }; |
| 539 | }; | 540 | }; |
| 540 | 541 | ||
| @@ -593,13 +594,29 @@ struct perf_event_mmap_page { · 52 unmodified lines | |||
| 593 | * ((rem * time_mult) >> time_shift); | 594 | * ((rem * time_mult) >> time_shift); |
| 594 | */ | 595 | */ |
| 595 | __u64 time_zero; | 596 | __u64 time_zero; |
| 597 | |||
| 596 | __u32 size; /* Header size up to __reserved[] fields. */ | 598 | __u32 size; /* Header size up to __reserved[] fields. */ |
| 599 | __u32 __reserved_1; | ||
| 600 | |||
| 601 | /* | ||
| 602 | * If cap_usr_time_short, the hardware clock is less than 64bit wide | ||
| 603 | * and we must compute the 'cyc' value, as used by cap_usr_time, as: | ||
| 604 | * | ||
| 605 | * cyc = time_cycles + ((cyc - time_cycles) & time_mask) | ||
| 606 | * | ||
| 607 | * NOTE: this form is explicitly chosen such that cap_usr_time_short | ||
| 608 | * is a correction on top of cap_usr_time, and code that doesn't | ||
| 609 | * know about cap_usr_time_short still works under the assumption | ||
| 610 | * the counter doesn't wrap. | ||
| 611 | */ | ||
| 612 | __u64 time_cycles; | ||
| 613 | __u64 time_mask; | ||
| 597 | 614 | ||
| 598 | /* | 615 | /* |
| 599 | * Hole for extension of the self monitor capabilities | 616 | * Hole for extension of the self monitor capabilities |
| 600 | */ | 617 | */ |
| 601 | 618 | ||
| 602 | __u8 __reserved[118*8+4]; /* align to 1k. */ | 619 | __u8 __reserved[116*8]; /* align to 1k. */ |
| 603 | 620 | ||
| 604 | /* | 621 | /* |
| 605 | * Control data for the mmap() data buffer. | 622 | * Control data for the mmap() data buffer. |
| @@ -1122,12 +1122,10 @@ maintain at least the appearance of FIFO order. · 1121 unmodified lines | |||
| 1122 | In practice, this difficulty is solved by inserting a special fence | 1122 | In practice, this difficulty is solved by inserting a special fence |
| 1123 | between P1's two loads when the kernel is compiled for the Alpha | 1123 | between P1's two loads when the kernel is compiled for the Alpha |
| 1124 | architecture. In fact, as of version 4.15, the kernel automatically | 1124 | architecture. In fact, as of version 4.15, the kernel automatically |
| 1125 | adds this fence (called smp_read_barrier_depends() and defined as | 1125 | adds this fence after every READ_ONCE() and atomic load on Alpha. The |
| 1126 | nothing at all on non-Alpha builds) after every READ_ONCE() and atomic | 1126 | effect of the fence is to cause the CPU not to execute any po-later |
| 1127 | load. The effect of the fence is to cause the CPU not to execute any | 1127 | instructions until after the local cache has finished processing all |
| 1128 | po-later instructions until after the local cache has finished | 1128 | the stores it has already received. Thus, if the code was changed to: |
| 1129 | processing all the stores it has already received. Thus, if the code | ||
| 1130 | was changed to: | ||
| 1131 | 1129 | ||
| 1132 | P1() | 1130 | P1() |
| 1133 | { | 1131 | { |
| @@ -1146,14 +1144,14 @@ READ_ONCE() or another synchronization primitive rather than accessed · 12 unmodified lines | |||
| 1146 | directly. | 1144 | directly. |
| 1147 | 1145 | ||
| 1148 | The LKMM requires that smp_rmb(), acquire fences, and strong fences | 1146 | The LKMM requires that smp_rmb(), acquire fences, and strong fences |
| 1149 | share this property with smp_read_barrier_depends(): They do not allow | 1147 | share this property: They do not allow the CPU to execute any po-later |
| 1150 | the CPU to execute any po-later instructions (or po-later loads in the | 1148 | instructions (or po-later loads in the case of smp_rmb()) until all |
| 1151 | case of smp_rmb()) until all outstanding stores have been processed by | 1149 | outstanding stores have been processed by the local cache. In the |
| 1152 | the local cache. In the case of a strong fence, the CPU first has to | 1150 | case of a strong fence, the CPU first has to wait for all of its |
| 1153 | wait for all of its po-earlier stores to propagate to every other CPU | 1151 | po-earlier stores to propagate to every other CPU in the system; then |
| 1154 | in the system; then it has to wait for the local cache to process all | 1152 | it has to wait for the local cache to process all the stores received |
| 1155 | the stores received as of that time -- not just the stores received | 1153 | as of that time -- not just the stores received when the strong fence |
| 1156 | when the strong fence began. | 1154 | began. |
| 1157 | 1155 | ||
| 1158 | And of course, none of this matters for any architecture other than | 1156 | And of course, none of this matters for any architecture other than |
| 1159 | Alpha. | 1157 | Alpha. |