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

Merge tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux

Pull arm64 updates from Will Deacon:
"The highlights are support for Arm's "Permission Overlay Extension"
using memory protection keys, support for running as a protected guest
on Android as well as perf support for a bunch of new interconnect
PMUs.

Summary:

ACPI:
- Enable PMCG erratum workaround for HiSilicon HIP10 and 11
platforms.
- Ensure arm64-specific IORT header is covered by MAINTAINERS.

CPU Errata:
- Enable workaround for hardware access/dirty issue on Ampere-1A
cores.

Memory management:
- Define PHYSMEM_END to fix a crash in the amdgpu driver.
- Avoid tripping over invalid kernel mappings on the kexec() path.
- Userspace support for the Permission Overlay Extension (POE) using
protection keys.

Perf and PMUs:
- Add support for the "fixed instruction counter" extension in the
CPU PMU architecture.
- Extend and fix the event encodings for Apple's M1 CPU PMU.
- Allow LSM hooks to decide on SPE permissions for physical
profiling.
- Add support for the CMN S3 and NI-700 PMUs.

Confidential Computing:
- Add support for booting an arm64 kernel as a protected guest under
Android's "Protected KVM" (pKVM) hypervisor.

Selftests:
- Fix vector length issues in the SVE/SME sigreturn tests
- Fix build warning in the ptrace tests.

Timers:
- Add support for PR_{G,S}ET_TSC so that 'rr' can deal with
non-determinism arising from the architected counter.

Miscellaneous:
- Rework our IPI-based CPU stopping code to try NMIs if regular IPIs
don't succeed.
- Minor fixes and cleanups"

* tag 'arm64-upstream' of git://git.kernel.org/pub/scm/linux/kernel/git/arm64/linux: (94 commits)
perf: arm-ni: Fix an NULL vs IS_ERR() bug
arm64: hibernate: Fix warning for cast from restricted gfp_t
arm64: esr: Define ESR_ELx_EC_* constants as UL
arm64: pkeys: remove redundant WARN
perf: arm_pmuv3: Use BR_RETIRED for HW branch event if enabled
MAINTAINERS: List Arm interconnect PMUs as supported
perf: Add driver for Arm NI-700 interconnect PMU
dt-bindings/perf: Add Arm NI-700 PMU
perf/arm-cmn: Improve format attr printing
perf/arm-cmn: Clean up unnecessary NUMA_NO_NODE check
arm64/mm: use lm_alias() with addresses passed to memblock_free()
mm: arm64: document why pte is not advanced in contpte_ptep_set_access_flags()
arm64: Expose the end of the linear map in PHYSMEM_END
arm64: trans_pgd: mark PTEs entries as valid to avoid dead kexec()
arm64/mm: Delete __init region from memblock.reserved
perf/arm-cmn: Support CMN S3
dt-bindings: perf: arm-cmn: Add CMN S3
perf/arm-cmn: Refactor DTC PMU register access
perf/arm-cmn: Make cycle counts less surprising
perf/arm-cmn: Improve build-time assertion
...

+3395 -893
+17
Documentation/admin-guide/perf/arm-ni.rst
··· 1 + ==================================== 2 + Arm Network-on Chip Interconnect PMU 3 + ==================================== 4 + 5 + NI-700 and friends implement a distinct PMU for each clock domain within the 6 + interconnect. Correspondingly, the driver exposes multiple PMU devices named 7 + arm_ni_<x>_cd_<y>, where <x> is an (arbitrary) instance identifier and <y> is 8 + the clock domain ID within that particular instance. If multiple NI instances 9 + exist within a system, the PMU devices can be correlated with the underlying 10 + hardware instance via sysfs parentage. 11 + 12 + Each PMU exposes base event aliases for the interface types present in its clock 13 + domain. These require qualifying with the "eventid" and "nodeid" parameters 14 + to specify the event code to count and the interface at which to count it 15 + (per the configured hardware ID as reflected in the xxNI_NODE_INFO register). 16 + The exception is the "cycles" alias for the PMU cycle counter, which is encoded 17 + with the PMU node type and needs no further qualification.
+8 -8
Documentation/admin-guide/perf/dwc_pcie_pmu.rst
··· 46 46 DesignWare Cores (DWC) PCIe PMU Driver 47 47 ======================================= 48 48 49 - This driver adds PMU devices for each PCIe Root Port named based on the BDF of 49 + This driver adds PMU devices for each PCIe Root Port named based on the SBDF of 50 50 the Root Port. For example, 51 51 52 - 30:03.0 PCI bridge: Device 1ded:8000 (rev 01) 52 + 0001:30:03.0 PCI bridge: Device 1ded:8000 (rev 01) 53 53 54 - the PMU device name for this Root Port is dwc_rootport_3018. 54 + the PMU device name for this Root Port is dwc_rootport_13018. 55 55 56 56 The DWC PCIe PMU driver registers a perf PMU driver, which provides 57 57 description of available events and configuration options in sysfs, see 58 - /sys/bus/event_source/devices/dwc_rootport_{bdf}. 58 + /sys/bus/event_source/devices/dwc_rootport_{sbdf}. 59 59 60 60 The "format" directory describes format of the config fields of the 61 61 perf_event_attr structure. The "events" directory provides configuration ··· 66 66 67 67 $# perf list | grep dwc_rootport 68 68 <...> 69 - dwc_rootport_3018/Rx_PCIe_TLP_Data_Payload/ [Kernel PMU event] 69 + dwc_rootport_13018/Rx_PCIe_TLP_Data_Payload/ [Kernel PMU event] 70 70 <...> 71 - dwc_rootport_3018/rx_memory_read,lane=?/ [Kernel PMU event] 71 + dwc_rootport_13018/rx_memory_read,lane=?/ [Kernel PMU event] 72 72 73 73 Time Based Analysis Event Usage 74 74 ------------------------------- 75 75 76 76 Example usage of counting PCIe RX TLP data payload (Units of bytes):: 77 77 78 - $# perf stat -a -e dwc_rootport_3018/Rx_PCIe_TLP_Data_Payload/ 78 + $# perf stat -a -e dwc_rootport_13018/Rx_PCIe_TLP_Data_Payload/ 79 79 80 80 The average RX/TX bandwidth can be calculated using the following formula: 81 81 ··· 88 88 Each lane has the same event set and to avoid generating a list of hundreds 89 89 of events, the user need to specify the lane ID explicitly, e.g.:: 90 90 91 - $# perf stat -a -e dwc_rootport_3018/rx_memory_read,lane=4/ 91 + $# perf stat -a -e dwc_rootport_13018/rx_memory_read,lane=4/ 92 92 93 93 The driver does not support sampling, therefore "perf record" will not 94 94 work. Per-task (without "-a") perf sessions are not supported.
+3 -1
Documentation/admin-guide/perf/hisi-pcie-pmu.rst
··· 28 28 PMU hardware device. 29 29 30 30 The "bus" sysfs file allows users to get the bus number of Root Ports 31 - monitored by PMU. 31 + monitored by PMU. Furthermore users can get the Root Ports range in 32 + [bdf_min, bdf_max] from "bdf_min" and "bdf_max" sysfs attributes 33 + respectively. 32 34 33 35 Example usage of perf:: 34 36
+1
Documentation/admin-guide/perf/index.rst
··· 16 16 starfive_starlink_pmu 17 17 arm-ccn 18 18 arm-cmn 19 + arm-ni 19 20 xgene-pmu 20 21 arm_dsu_pmu 21 22 thunderx2-pmu
+2
Documentation/arch/arm64/elf_hwcaps.rst
··· 365 365 HWCAP2_SME_SF8DP4 366 366 Functionality implied by ID_AA64SMFR0_EL1.SF8DP4 == 0b1. 367 367 368 + HWCAP2_POE 369 + Functionality implied by ID_AA64MMFR3_EL1.S1POE == 0b0001. 368 370 369 371 4. Unused AT_HWCAP bits 370 372 -----------------------
+4 -2
Documentation/arch/arm64/silicon-errata.rst
··· 55 55 +----------------+-----------------+-----------------+-----------------------------+ 56 56 | Ampere | AmpereOne | AC03_CPU_38 | AMPERE_ERRATUM_AC03_CPU_38 | 57 57 +----------------+-----------------+-----------------+-----------------------------+ 58 + | Ampere | AmpereOne AC04 | AC04_CPU_10 | AMPERE_ERRATUM_AC03_CPU_38 | 59 + +----------------+-----------------+-----------------+-----------------------------+ 58 60 +----------------+-----------------+-----------------+-----------------------------+ 59 61 | ARM | Cortex-A510 | #2457168 | ARM64_ERRATUM_2457168 | 60 62 +----------------+-----------------+-----------------+-----------------------------+ ··· 251 249 +----------------+-----------------+-----------------+-----------------------------+ 252 250 | Hisilicon | Hip08 SMMU PMCG | #162001800 | N/A | 253 251 +----------------+-----------------+-----------------+-----------------------------+ 254 - | Hisilicon | Hip08 SMMU PMCG | #162001900 | N/A | 255 - | | Hip09 SMMU PMCG | | | 252 + | Hisilicon | Hip{08,09,10,10C| #162001900 | N/A | 253 + | | ,11} SMMU PMCG | | | 256 254 +----------------+-----------------+-----------------+-----------------------------+ 257 255 +----------------+-----------------+-----------------+-----------------------------+ 258 256 | Qualcomm Tech. | Kryo/Falkor v1 | E1003 | QCOM_FALKOR_ERRATUM_1003 |
+1
Documentation/devicetree/bindings/perf/arm,cmn.yaml
··· 16 16 - arm,cmn-600 17 17 - arm,cmn-650 18 18 - arm,cmn-700 19 + - arm,cmn-s3 19 20 - arm,ci-700 20 21 21 22 reg:
+30
Documentation/devicetree/bindings/perf/arm,ni.yaml
··· 1 + # SPDX-License-Identifier: GPL-2.0-only OR BSD-2-Clause 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/perf/arm,ni.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Arm NI (Network-on-Chip Interconnect) Performance Monitors 8 + 9 + maintainers: 10 + - Robin Murphy <robin.murphy@arm.com> 11 + 12 + properties: 13 + compatible: 14 + const: arm,ni-700 15 + 16 + reg: 17 + items: 18 + - description: Complete configuration register space 19 + 20 + interrupts: 21 + minItems: 1 22 + maxItems: 32 23 + description: Overflow interrupts, one per clock domain, in order of domain ID 24 + 25 + required: 26 + - compatible 27 + - reg 28 + - interrupts 29 + 30 + additionalProperties: false
+98
Documentation/virt/kvm/arm/hypercalls.rst
··· 44 44 ---------------------------------------- 45 45 46 46 See ptp_kvm.rst 47 + 48 + ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO`` 49 + ---------------------------------- 50 + 51 + Query the memory protection parameters for a pKVM protected virtual machine. 52 + 53 + +---------------------+-------------------------------------------------------------+ 54 + | Presence: | Optional; pKVM protected guests only. | 55 + +---------------------+-------------------------------------------------------------+ 56 + | Calling convention: | HVC64 | 57 + +---------------------+----------+--------------------------------------------------+ 58 + | Function ID: | (uint32) | 0xC6000002 | 59 + +---------------------+----------+----+---------------------------------------------+ 60 + | Arguments: | (uint64) | R1 | Reserved / Must be zero | 61 + | +----------+----+---------------------------------------------+ 62 + | | (uint64) | R2 | Reserved / Must be zero | 63 + | +----------+----+---------------------------------------------+ 64 + | | (uint64) | R3 | Reserved / Must be zero | 65 + +---------------------+----------+----+---------------------------------------------+ 66 + | Return Values: | (int64) | R0 | ``INVALID_PARAMETER (-3)`` on error, else | 67 + | | | | memory protection granule in bytes | 68 + +---------------------+----------+----+---------------------------------------------+ 69 + 70 + ``ARM_SMCCC_KVM_FUNC_MEM_SHARE`` 71 + -------------------------------- 72 + 73 + Share a region of memory with the KVM host, granting it read, write and execute 74 + permissions. The size of the region is equal to the memory protection granule 75 + advertised by ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``. 76 + 77 + +---------------------+-------------------------------------------------------------+ 78 + | Presence: | Optional; pKVM protected guests only. | 79 + +---------------------+-------------------------------------------------------------+ 80 + | Calling convention: | HVC64 | 81 + +---------------------+----------+--------------------------------------------------+ 82 + | Function ID: | (uint32) | 0xC6000003 | 83 + +---------------------+----------+----+---------------------------------------------+ 84 + | Arguments: | (uint64) | R1 | Base IPA of memory region to share | 85 + | +----------+----+---------------------------------------------+ 86 + | | (uint64) | R2 | Reserved / Must be zero | 87 + | +----------+----+---------------------------------------------+ 88 + | | (uint64) | R3 | Reserved / Must be zero | 89 + +---------------------+----------+----+---------------------------------------------+ 90 + | Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 91 + | | | +---------------------------------------------+ 92 + | | | | ``INVALID_PARAMETER (-3)`` | 93 + +---------------------+----------+----+---------------------------------------------+ 94 + 95 + ``ARM_SMCCC_KVM_FUNC_MEM_UNSHARE`` 96 + ---------------------------------- 97 + 98 + Revoke access permission from the KVM host to a memory region previously shared 99 + with ``ARM_SMCCC_KVM_FUNC_MEM_SHARE``. The size of the region is equal to the 100 + memory protection granule advertised by ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``. 101 + 102 + +---------------------+-------------------------------------------------------------+ 103 + | Presence: | Optional; pKVM protected guests only. | 104 + +---------------------+-------------------------------------------------------------+ 105 + | Calling convention: | HVC64 | 106 + +---------------------+----------+--------------------------------------------------+ 107 + | Function ID: | (uint32) | 0xC6000004 | 108 + +---------------------+----------+----+---------------------------------------------+ 109 + | Arguments: | (uint64) | R1 | Base IPA of memory region to unshare | 110 + | +----------+----+---------------------------------------------+ 111 + | | (uint64) | R2 | Reserved / Must be zero | 112 + | +----------+----+---------------------------------------------+ 113 + | | (uint64) | R3 | Reserved / Must be zero | 114 + +---------------------+----------+----+---------------------------------------------+ 115 + | Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 116 + | | | +---------------------------------------------+ 117 + | | | | ``INVALID_PARAMETER (-3)`` | 118 + +---------------------+----------+----+---------------------------------------------+ 119 + 120 + ``ARM_SMCCC_KVM_FUNC_MMIO_GUARD`` 121 + ---------------------------------- 122 + 123 + Request that a given memory region is handled as MMIO by the hypervisor, 124 + allowing accesses to this region to be emulated by the KVM host. The size of the 125 + region is equal to the memory protection granule advertised by 126 + ``ARM_SMCCC_KVM_FUNC_HYP_MEMINFO``. 127 + 128 + +---------------------+-------------------------------------------------------------+ 129 + | Presence: | Optional; pKVM protected guests only. | 130 + +---------------------+-------------------------------------------------------------+ 131 + | Calling convention: | HVC64 | 132 + +---------------------+----------+--------------------------------------------------+ 133 + | Function ID: | (uint32) | 0xC6000007 | 134 + +---------------------+----------+----+---------------------------------------------+ 135 + | Arguments: | (uint64) | R1 | Base IPA of MMIO memory region | 136 + | +----------+----+---------------------------------------------+ 137 + | | (uint64) | R2 | Reserved / Must be zero | 138 + | +----------+----+---------------------------------------------+ 139 + | | (uint64) | R3 | Reserved / Must be zero | 140 + +---------------------+----------+----+---------------------------------------------+ 141 + | Return Values: | (int64) | R0 | ``SUCCESS (0)`` | 142 + | | | +---------------------------------------------+ 143 + | | | | ``INVALID_PARAMETER (-3)`` | 144 + +---------------------+----------+----+---------------------------------------------+
+12
MAINTAINERS
··· 334 334 L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers) 335 335 S: Maintained 336 336 F: drivers/acpi/arm64 337 + F: include/linux/acpi_iort.h 337 338 338 339 ACPI FOR RISC-V (ACPI/riscv) 339 340 M: Sunil V L <sunilvl@ventanamicro.com> ··· 1752 1751 F: drivers/mtd/maps/physmap-versatile.* 1753 1752 F: drivers/power/reset/arm-versatile-reboot.c 1754 1753 F: drivers/soc/versatile/ 1754 + 1755 + ARM INTERCONNECT PMU DRIVERS 1756 + M: Robin Murphy <robin.murphy@arm.com> 1757 + S: Supported 1758 + F: Documentation/admin-guide/perf/arm-cmn.rst 1759 + F: Documentation/admin-guide/perf/arm-ni.rst 1760 + F: Documentation/devicetree/bindings/perf/arm,cmn.yaml 1761 + F: Documentation/devicetree/bindings/perf/arm,ni.yaml 1762 + F: drivers/perf/arm-cmn.c 1763 + F: drivers/perf/arm-ni.c 1764 + F: tools/perf/pmu-events/arch/arm64/arm/cmn/ 1755 1765 1756 1766 ARM KOMEDA DRM-KMS DRIVER 1757 1767 M: Liviu Dudau <liviu.dudau@arm.com>
+20
arch/arm/include/asm/arm_pmuv3.h
··· 127 127 return (dfr0 >> 24) & 0xf; 128 128 } 129 129 130 + static inline bool pmuv3_has_icntr(void) 131 + { 132 + /* FEAT_PMUv3_ICNTR not accessible for 32-bit */ 133 + return false; 134 + } 135 + 130 136 static inline void write_pmcr(u32 val) 131 137 { 132 138 write_sysreg(val, PMCR); ··· 158 152 return read_sysreg(PMCCNTR); 159 153 } 160 154 155 + static inline void write_pmicntr(u64 val) {} 156 + 157 + static inline u64 read_pmicntr(void) 158 + { 159 + return 0; 160 + } 161 + 161 162 static inline void write_pmcntenset(u32 val) 162 163 { 163 164 write_sysreg(val, PMCNTENSET); ··· 188 175 static inline void write_pmccfiltr(u32 val) 189 176 { 190 177 write_sysreg(val, PMCCFILTR); 178 + } 179 + 180 + static inline void write_pmicfiltr(u64 val) {} 181 + 182 + static inline u64 read_pmicfiltr(void) 183 + { 184 + return 0; 191 185 } 192 186 193 187 static inline void write_pmovsclr(u32 val)
+2
arch/arm/include/asm/hypervisor.h
··· 7 7 void kvm_init_hyp_services(void); 8 8 bool kvm_arm_hyp_service_available(u32 func_id); 9 9 10 + static inline void kvm_arch_init_hyp_services(void) { }; 11 + 10 12 #endif
+25 -1
arch/arm64/Kconfig
··· 34 34 select ARCH_HAS_KERNEL_FPU_SUPPORT if KERNEL_MODE_NEON 35 35 select ARCH_HAS_KEEPINITRD 36 36 select ARCH_HAS_MEMBARRIER_SYNC_CORE 37 + select ARCH_HAS_MEM_ENCRYPT 37 38 select ARCH_HAS_NMI_SAFE_THIS_CPU_OPS 38 39 select ARCH_HAS_NON_OVERLAPPING_ADDRESS_SPACE 39 40 select ARCH_HAS_PTE_DEVMAP ··· 424 423 default y 425 424 help 426 425 This option adds an alternative code sequence to work around Ampere 427 - erratum AC03_CPU_38 on AmpereOne. 426 + errata AC03_CPU_38 and AC04_CPU_10 on AmpereOne. 428 427 429 428 The affected design reports FEAT_HAFDBS as not implemented in 430 429 ID_AA64MMFR1_EL1.HAFDBS, but (V)TCR_ELx.{HA,HD} are not RES0 ··· 2137 2136 The feature is detected at runtime, and will remain disabled 2138 2137 if the cpu does not implement the feature. 2139 2138 endmenu # "ARMv8.7 architectural features" 2139 + 2140 + menu "ARMv8.9 architectural features" 2141 + 2142 + config ARM64_POE 2143 + prompt "Permission Overlay Extension" 2144 + def_bool y 2145 + select ARCH_USES_HIGH_VMA_FLAGS 2146 + select ARCH_HAS_PKEYS 2147 + help 2148 + The Permission Overlay Extension is used to implement Memory 2149 + Protection Keys. Memory Protection Keys provides a mechanism for 2150 + enforcing page-based protections, but without requiring modification 2151 + of the page tables when an application changes protection domains. 2152 + 2153 + For details, see Documentation/core-api/protection-keys.rst 2154 + 2155 + If unsure, say y. 2156 + 2157 + config ARCH_PKEY_BITS 2158 + int 2159 + default 3 2160 + 2161 + endmenu # "ARMv8.9 architectural features" 2140 2162 2141 2163 config ARM64_SVE 2142 2164 bool "ARM Scalable Vector Extension support"
+47 -6
arch/arm64/include/asm/arm_pmuv3.h
··· 33 33 PMEVN_SWITCH(n, WRITE_PMEVTYPERN); 34 34 } 35 35 36 + #define RETURN_READ_PMEVTYPERN(n) \ 37 + return read_sysreg(pmevtyper##n##_el0) 38 + static inline unsigned long read_pmevtypern(int n) 39 + { 40 + PMEVN_SWITCH(n, RETURN_READ_PMEVTYPERN); 41 + return 0; 42 + } 43 + 36 44 static inline unsigned long read_pmmir(void) 37 45 { 38 46 return read_cpuid(PMMIR_EL1); ··· 52 44 53 45 return cpuid_feature_extract_unsigned_field(dfr0, 54 46 ID_AA64DFR0_EL1_PMUVer_SHIFT); 47 + } 48 + 49 + static inline bool pmuv3_has_icntr(void) 50 + { 51 + u64 dfr1 = read_sysreg(id_aa64dfr1_el1); 52 + 53 + return !!cpuid_feature_extract_unsigned_field(dfr1, 54 + ID_AA64DFR1_EL1_PMICNTR_SHIFT); 55 55 } 56 56 57 57 static inline void write_pmcr(u64 val) ··· 87 71 return read_sysreg(pmccntr_el0); 88 72 } 89 73 90 - static inline void write_pmcntenset(u32 val) 74 + static inline void write_pmicntr(u64 val) 75 + { 76 + write_sysreg_s(val, SYS_PMICNTR_EL0); 77 + } 78 + 79 + static inline u64 read_pmicntr(void) 80 + { 81 + return read_sysreg_s(SYS_PMICNTR_EL0); 82 + } 83 + 84 + static inline void write_pmcntenset(u64 val) 91 85 { 92 86 write_sysreg(val, pmcntenset_el0); 93 87 } 94 88 95 - static inline void write_pmcntenclr(u32 val) 89 + static inline void write_pmcntenclr(u64 val) 96 90 { 97 91 write_sysreg(val, pmcntenclr_el0); 98 92 } 99 93 100 - static inline void write_pmintenset(u32 val) 94 + static inline void write_pmintenset(u64 val) 101 95 { 102 96 write_sysreg(val, pmintenset_el1); 103 97 } 104 98 105 - static inline void write_pmintenclr(u32 val) 99 + static inline void write_pmintenclr(u64 val) 106 100 { 107 101 write_sysreg(val, pmintenclr_el1); 108 102 } ··· 122 96 write_sysreg(val, pmccfiltr_el0); 123 97 } 124 98 125 - static inline void write_pmovsclr(u32 val) 99 + static inline u64 read_pmccfiltr(void) 100 + { 101 + return read_sysreg(pmccfiltr_el0); 102 + } 103 + 104 + static inline void write_pmicfiltr(u64 val) 105 + { 106 + write_sysreg_s(val, SYS_PMICFILTR_EL0); 107 + } 108 + 109 + static inline u64 read_pmicfiltr(void) 110 + { 111 + return read_sysreg_s(SYS_PMICFILTR_EL0); 112 + } 113 + 114 + static inline void write_pmovsclr(u64 val) 126 115 { 127 116 write_sysreg(val, pmovsclr_el0); 128 117 } 129 118 130 - static inline u32 read_pmovsclr(void) 119 + static inline u64 read_pmovsclr(void) 131 120 { 132 121 return read_sysreg(pmovsclr_el0); 133 122 }
+6
arch/arm64/include/asm/cpufeature.h
··· 832 832 return cpus_have_final_cap(ARM64_HAS_LPA2); 833 833 } 834 834 835 + static inline bool system_supports_poe(void) 836 + { 837 + return IS_ENABLED(CONFIG_ARM64_POE) && 838 + alternative_has_cap_unlikely(ARM64_HAS_S1POE); 839 + } 840 + 835 841 int do_emulate_mrs(struct pt_regs *regs, u32 sys_reg, u32 rt); 836 842 bool try_emulate_mrs(struct pt_regs *regs, u32 isn); 837 843
+2
arch/arm64/include/asm/cputype.h
··· 143 143 #define APPLE_CPU_PART_M2_AVALANCHE_MAX 0x039 144 144 145 145 #define AMPERE_CPU_PART_AMPERE1 0xAC3 146 + #define AMPERE_CPU_PART_AMPERE1A 0xAC4 146 147 147 148 #define MICROSOFT_CPU_PART_AZURE_COBALT_100 0xD49 /* Based on r0p0 of ARM Neoverse N2 */ 148 149 ··· 213 212 #define MIDR_APPLE_M2_BLIZZARD_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_BLIZZARD_MAX) 214 213 #define MIDR_APPLE_M2_AVALANCHE_MAX MIDR_CPU_MODEL(ARM_CPU_IMP_APPLE, APPLE_CPU_PART_M2_AVALANCHE_MAX) 215 214 #define MIDR_AMPERE1 MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1) 215 + #define MIDR_AMPERE1A MIDR_CPU_MODEL(ARM_CPU_IMP_AMPERE, AMPERE_CPU_PART_AMPERE1A) 216 216 #define MIDR_MICROSOFT_AZURE_COBALT_100 MIDR_CPU_MODEL(ARM_CPU_IMP_MICROSOFT, MICROSOFT_CPU_PART_AZURE_COBALT_100) 217 217 218 218 /* Fujitsu Erratum 010001 affects A64FX 1.0 and 1.1, (v0r0 and v1r0) */
+18 -7
arch/arm64/include/asm/el2_setup.h
··· 165 165 mrs x1, id_aa64dfr0_el1 166 166 ubfx x1, x1, #ID_AA64DFR0_EL1_PMSVer_SHIFT, #4 167 167 cmp x1, #3 168 - b.lt .Lset_debug_fgt_\@ 168 + b.lt .Lskip_spe_fgt_\@ 169 169 /* Disable PMSNEVFR_EL1 read and write traps */ 170 170 orr x0, x0, #(1 << 62) 171 171 172 - .Lset_debug_fgt_\@: 172 + .Lskip_spe_fgt_\@: 173 173 msr_s SYS_HDFGRTR_EL2, x0 174 174 msr_s SYS_HDFGWTR_EL2, x0 175 175 176 176 mov x0, xzr 177 177 mrs x1, id_aa64pfr1_el1 178 178 ubfx x1, x1, #ID_AA64PFR1_EL1_SME_SHIFT, #4 179 - cbz x1, .Lset_pie_fgt_\@ 179 + cbz x1, .Lskip_debug_fgt_\@ 180 180 181 181 /* Disable nVHE traps of TPIDR2 and SMPRI */ 182 182 orr x0, x0, #HFGxTR_EL2_nSMPRI_EL1_MASK 183 183 orr x0, x0, #HFGxTR_EL2_nTPIDR2_EL0_MASK 184 184 185 - .Lset_pie_fgt_\@: 185 + .Lskip_debug_fgt_\@: 186 186 mrs_s x1, SYS_ID_AA64MMFR3_EL1 187 187 ubfx x1, x1, #ID_AA64MMFR3_EL1_S1PIE_SHIFT, #4 188 - cbz x1, .Lset_fgt_\@ 188 + cbz x1, .Lskip_pie_fgt_\@ 189 189 190 190 /* Disable trapping of PIR_EL1 / PIRE0_EL1 */ 191 191 orr x0, x0, #HFGxTR_EL2_nPIR_EL1 192 192 orr x0, x0, #HFGxTR_EL2_nPIRE0_EL1 193 193 194 - .Lset_fgt_\@: 194 + .Lskip_pie_fgt_\@: 195 + mrs_s x1, SYS_ID_AA64MMFR3_EL1 196 + ubfx x1, x1, #ID_AA64MMFR3_EL1_S1POE_SHIFT, #4 197 + cbz x1, .Lskip_poe_fgt_\@ 198 + 199 + /* Disable trapping of POR_EL0 */ 200 + orr x0, x0, #HFGxTR_EL2_nPOR_EL0 201 + 202 + .Lskip_poe_fgt_\@: 195 203 msr_s SYS_HFGRTR_EL2, x0 196 204 msr_s SYS_HFGWTR_EL2, x0 197 205 msr_s SYS_HFGITR_EL2, xzr 198 206 199 207 mrs x1, id_aa64pfr0_el1 // AMU traps UNDEF without AMU 200 208 ubfx x1, x1, #ID_AA64PFR0_EL1_AMU_SHIFT, #4 201 - cbz x1, .Lskip_fgt_\@ 209 + cbz x1, .Lskip_amu_fgt_\@ 202 210 203 211 msr_s SYS_HAFGRTR_EL2, xzr 212 + 213 + .Lskip_amu_fgt_\@: 214 + 204 215 .Lskip_fgt_\@: 205 216 .endm 206 217
+44 -44
arch/arm64/include/asm/esr.h
··· 10 10 #include <asm/memory.h> 11 11 #include <asm/sysreg.h> 12 12 13 - #define ESR_ELx_EC_UNKNOWN (0x00) 14 - #define ESR_ELx_EC_WFx (0x01) 13 + #define ESR_ELx_EC_UNKNOWN UL(0x00) 14 + #define ESR_ELx_EC_WFx UL(0x01) 15 15 /* Unallocated EC: 0x02 */ 16 - #define ESR_ELx_EC_CP15_32 (0x03) 17 - #define ESR_ELx_EC_CP15_64 (0x04) 18 - #define ESR_ELx_EC_CP14_MR (0x05) 19 - #define ESR_ELx_EC_CP14_LS (0x06) 20 - #define ESR_ELx_EC_FP_ASIMD (0x07) 21 - #define ESR_ELx_EC_CP10_ID (0x08) /* EL2 only */ 22 - #define ESR_ELx_EC_PAC (0x09) /* EL2 and above */ 16 + #define ESR_ELx_EC_CP15_32 UL(0x03) 17 + #define ESR_ELx_EC_CP15_64 UL(0x04) 18 + #define ESR_ELx_EC_CP14_MR UL(0x05) 19 + #define ESR_ELx_EC_CP14_LS UL(0x06) 20 + #define ESR_ELx_EC_FP_ASIMD UL(0x07) 21 + #define ESR_ELx_EC_CP10_ID UL(0x08) /* EL2 only */ 22 + #define ESR_ELx_EC_PAC UL(0x09) /* EL2 and above */ 23 23 /* Unallocated EC: 0x0A - 0x0B */ 24 - #define ESR_ELx_EC_CP14_64 (0x0C) 25 - #define ESR_ELx_EC_BTI (0x0D) 26 - #define ESR_ELx_EC_ILL (0x0E) 24 + #define ESR_ELx_EC_CP14_64 UL(0x0C) 25 + #define ESR_ELx_EC_BTI UL(0x0D) 26 + #define ESR_ELx_EC_ILL UL(0x0E) 27 27 /* Unallocated EC: 0x0F - 0x10 */ 28 - #define ESR_ELx_EC_SVC32 (0x11) 29 - #define ESR_ELx_EC_HVC32 (0x12) /* EL2 only */ 30 - #define ESR_ELx_EC_SMC32 (0x13) /* EL2 and above */ 28 + #define ESR_ELx_EC_SVC32 UL(0x11) 29 + #define ESR_ELx_EC_HVC32 UL(0x12) /* EL2 only */ 30 + #define ESR_ELx_EC_SMC32 UL(0x13) /* EL2 and above */ 31 31 /* Unallocated EC: 0x14 */ 32 - #define ESR_ELx_EC_SVC64 (0x15) 33 - #define ESR_ELx_EC_HVC64 (0x16) /* EL2 and above */ 34 - #define ESR_ELx_EC_SMC64 (0x17) /* EL2 and above */ 35 - #define ESR_ELx_EC_SYS64 (0x18) 36 - #define ESR_ELx_EC_SVE (0x19) 37 - #define ESR_ELx_EC_ERET (0x1a) /* EL2 only */ 32 + #define ESR_ELx_EC_SVC64 UL(0x15) 33 + #define ESR_ELx_EC_HVC64 UL(0x16) /* EL2 and above */ 34 + #define ESR_ELx_EC_SMC64 UL(0x17) /* EL2 and above */ 35 + #define ESR_ELx_EC_SYS64 UL(0x18) 36 + #define ESR_ELx_EC_SVE UL(0x19) 37 + #define ESR_ELx_EC_ERET UL(0x1a) /* EL2 only */ 38 38 /* Unallocated EC: 0x1B */ 39 - #define ESR_ELx_EC_FPAC (0x1C) /* EL1 and above */ 40 - #define ESR_ELx_EC_SME (0x1D) 39 + #define ESR_ELx_EC_FPAC UL(0x1C) /* EL1 and above */ 40 + #define ESR_ELx_EC_SME UL(0x1D) 41 41 /* Unallocated EC: 0x1E */ 42 - #define ESR_ELx_EC_IMP_DEF (0x1f) /* EL3 only */ 43 - #define ESR_ELx_EC_IABT_LOW (0x20) 44 - #define ESR_ELx_EC_IABT_CUR (0x21) 45 - #define ESR_ELx_EC_PC_ALIGN (0x22) 42 + #define ESR_ELx_EC_IMP_DEF UL(0x1f) /* EL3 only */ 43 + #define ESR_ELx_EC_IABT_LOW UL(0x20) 44 + #define ESR_ELx_EC_IABT_CUR UL(0x21) 45 + #define ESR_ELx_EC_PC_ALIGN UL(0x22) 46 46 /* Unallocated EC: 0x23 */ 47 - #define ESR_ELx_EC_DABT_LOW (0x24) 48 - #define ESR_ELx_EC_DABT_CUR (0x25) 49 - #define ESR_ELx_EC_SP_ALIGN (0x26) 50 - #define ESR_ELx_EC_MOPS (0x27) 51 - #define ESR_ELx_EC_FP_EXC32 (0x28) 47 + #define ESR_ELx_EC_DABT_LOW UL(0x24) 48 + #define ESR_ELx_EC_DABT_CUR UL(0x25) 49 + #define ESR_ELx_EC_SP_ALIGN UL(0x26) 50 + #define ESR_ELx_EC_MOPS UL(0x27) 51 + #define ESR_ELx_EC_FP_EXC32 UL(0x28) 52 52 /* Unallocated EC: 0x29 - 0x2B */ 53 - #define ESR_ELx_EC_FP_EXC64 (0x2C) 53 + #define ESR_ELx_EC_FP_EXC64 UL(0x2C) 54 54 /* Unallocated EC: 0x2D - 0x2E */ 55 - #define ESR_ELx_EC_SERROR (0x2F) 56 - #define ESR_ELx_EC_BREAKPT_LOW (0x30) 57 - #define ESR_ELx_EC_BREAKPT_CUR (0x31) 58 - #define ESR_ELx_EC_SOFTSTP_LOW (0x32) 59 - #define ESR_ELx_EC_SOFTSTP_CUR (0x33) 60 - #define ESR_ELx_EC_WATCHPT_LOW (0x34) 61 - #define ESR_ELx_EC_WATCHPT_CUR (0x35) 55 + #define ESR_ELx_EC_SERROR UL(0x2F) 56 + #define ESR_ELx_EC_BREAKPT_LOW UL(0x30) 57 + #define ESR_ELx_EC_BREAKPT_CUR UL(0x31) 58 + #define ESR_ELx_EC_SOFTSTP_LOW UL(0x32) 59 + #define ESR_ELx_EC_SOFTSTP_CUR UL(0x33) 60 + #define ESR_ELx_EC_WATCHPT_LOW UL(0x34) 61 + #define ESR_ELx_EC_WATCHPT_CUR UL(0x35) 62 62 /* Unallocated EC: 0x36 - 0x37 */ 63 - #define ESR_ELx_EC_BKPT32 (0x38) 63 + #define ESR_ELx_EC_BKPT32 UL(0x38) 64 64 /* Unallocated EC: 0x39 */ 65 - #define ESR_ELx_EC_VECTOR32 (0x3A) /* EL2 only */ 65 + #define ESR_ELx_EC_VECTOR32 UL(0x3A) /* EL2 only */ 66 66 /* Unallocated EC: 0x3B */ 67 - #define ESR_ELx_EC_BRK64 (0x3C) 67 + #define ESR_ELx_EC_BRK64 UL(0x3C) 68 68 /* Unallocated EC: 0x3D - 0x3F */ 69 - #define ESR_ELx_EC_MAX (0x3F) 69 + #define ESR_ELx_EC_MAX UL(0x3F) 70 70 71 71 #define ESR_ELx_EC_SHIFT (26) 72 72 #define ESR_ELx_EC_WIDTH (6)
-2
arch/arm64/include/asm/fpsimd.h
··· 155 155 extern void cpu_enable_fa64(const struct arm64_cpu_capabilities *__unused); 156 156 extern void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__unused); 157 157 158 - extern u64 read_smcr_features(void); 159 - 160 158 /* 161 159 * Helpers to translate bit indices in sve_vq_map to VQ values (and 162 160 * vice versa). This allows find_next_bit() to be used to find the
+1
arch/arm64/include/asm/hwcap.h
··· 157 157 #define KERNEL_HWCAP_SME_SF8FMA __khwcap2_feature(SME_SF8FMA) 158 158 #define KERNEL_HWCAP_SME_SF8DP4 __khwcap2_feature(SME_SF8DP4) 159 159 #define KERNEL_HWCAP_SME_SF8DP2 __khwcap2_feature(SME_SF8DP2) 160 + #define KERNEL_HWCAP_POE __khwcap2_feature(POE) 160 161 161 162 /* 162 163 * This yields a mask that user programs can use to figure out what
+11
arch/arm64/include/asm/hypervisor.h
··· 7 7 void kvm_init_hyp_services(void); 8 8 bool kvm_arm_hyp_service_available(u32 func_id); 9 9 10 + #ifdef CONFIG_ARM_PKVM_GUEST 11 + void pkvm_init_hyp_services(void); 12 + #else 13 + static inline void pkvm_init_hyp_services(void) { }; 14 + #endif 15 + 16 + static inline void kvm_arch_init_hyp_services(void) 17 + { 18 + pkvm_init_hyp_services(); 19 + }; 20 + 10 21 #endif
+4
arch/arm64/include/asm/io.h
··· 271 271 * I/O memory mapping functions. 272 272 */ 273 273 274 + typedef int (*ioremap_prot_hook_t)(phys_addr_t phys_addr, size_t size, 275 + pgprot_t *prot); 276 + int arm64_ioremap_prot_hook_register(const ioremap_prot_hook_t hook); 277 + 274 278 #define ioremap_prot ioremap_prot 275 279 276 280 #define _PAGE_IOREMAP PROT_DEVICE_nGnRE
+2 -1
arch/arm64/include/asm/kvm_asm.h
··· 10 10 #include <asm/hyp_image.h> 11 11 #include <asm/insn.h> 12 12 #include <asm/virt.h> 13 + #include <asm/sysreg.h> 13 14 14 15 #define ARM_EXIT_WITH_SERROR_BIT 31 15 16 #define ARM_EXCEPTION_CODE(x) ((x) & ~(1U << ARM_EXIT_WITH_SERROR_BIT)) ··· 260 259 asm volatile( \ 261 260 " mrs %1, spsr_el2\n" \ 262 261 " mrs %2, elr_el2\n" \ 263 - "1: at "at_op", %3\n" \ 262 + "1: " __msr_s(at_op, "%3") "\n" \ 264 263 " isb\n" \ 265 264 " b 9f\n" \ 266 265 "2: msr spsr_el2, %1\n" \
+8 -4
arch/arm64/include/asm/kvm_host.h
··· 446 446 GCR_EL1, /* Tag Control Register */ 447 447 TFSRE0_EL1, /* Tag Fault Status Register (EL0) */ 448 448 449 + POR_EL0, /* Permission Overlay Register 0 (EL0) */ 450 + 449 451 /* 32bit specific registers. */ 450 452 DACR32_EL2, /* Domain Access Control Register */ 451 453 IFSR32_EL2, /* Instruction Fault Status Register */ ··· 518 516 /* Permission Indirection Extension registers */ 519 517 VNCR(PIR_EL1), /* Permission Indirection Register 1 (EL1) */ 520 518 VNCR(PIRE0_EL1), /* Permission Indirection Register 0 (EL1) */ 519 + 520 + VNCR(POR_EL1), /* Permission Overlay Register 1 (EL1) */ 521 521 522 522 VNCR(HFGRTR_EL2), 523 523 VNCR(HFGWTR_EL2), ··· 1334 1330 void kvm_arch_vcpu_put_debug_state_flags(struct kvm_vcpu *vcpu); 1335 1331 1336 1332 #ifdef CONFIG_KVM 1337 - void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr); 1338 - void kvm_clr_pmu_events(u32 clr); 1333 + void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr); 1334 + void kvm_clr_pmu_events(u64 clr); 1339 1335 bool kvm_set_pmuserenr(u64 val); 1340 1336 #else 1341 - static inline void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) {} 1342 - static inline void kvm_clr_pmu_events(u32 clr) {} 1337 + static inline void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) {} 1338 + static inline void kvm_clr_pmu_events(u64 clr) {} 1343 1339 static inline bool kvm_set_pmuserenr(u64 val) 1344 1340 { 1345 1341 return false;
+15
arch/arm64/include/asm/mem_encrypt.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0-only */ 2 + #ifndef __ASM_MEM_ENCRYPT_H 3 + #define __ASM_MEM_ENCRYPT_H 4 + 5 + struct arm64_mem_crypt_ops { 6 + int (*encrypt)(unsigned long addr, int numpages); 7 + int (*decrypt)(unsigned long addr, int numpages); 8 + }; 9 + 10 + int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops); 11 + 12 + int set_memory_encrypted(unsigned long addr, int numpages); 13 + int set_memory_decrypted(unsigned long addr, int numpages); 14 + 15 + #endif /* __ASM_MEM_ENCRYPT_H */
+2
arch/arm64/include/asm/memory.h
··· 110 110 #define PAGE_END (_PAGE_END(VA_BITS_MIN)) 111 111 #endif /* CONFIG_KASAN */ 112 112 113 + #define PHYSMEM_END __pa(PAGE_END - 1) 114 + 113 115 #define MIN_THREAD_SHIFT (14 + KASAN_THREAD_SHIFT) 114 116 115 117 /*
+9 -1
arch/arm64/include/asm/mman.h
··· 7 7 #include <uapi/asm/mman.h> 8 8 9 9 static inline unsigned long arch_calc_vm_prot_bits(unsigned long prot, 10 - unsigned long pkey __always_unused) 10 + unsigned long pkey) 11 11 { 12 12 unsigned long ret = 0; 13 13 ··· 16 16 17 17 if (system_supports_mte() && (prot & PROT_MTE)) 18 18 ret |= VM_MTE; 19 + 20 + #ifdef CONFIG_ARCH_HAS_PKEYS 21 + if (system_supports_poe()) { 22 + ret |= pkey & BIT(0) ? VM_PKEY_BIT0 : 0; 23 + ret |= pkey & BIT(1) ? VM_PKEY_BIT1 : 0; 24 + ret |= pkey & BIT(2) ? VM_PKEY_BIT2 : 0; 25 + } 26 + #endif 19 27 20 28 return ret; 21 29 }
+1 -1
arch/arm64/include/asm/mmu.h
··· 25 25 refcount_t pinned; 26 26 void *vdso; 27 27 unsigned long flags; 28 + u8 pkey_allocation_map; 28 29 } mm_context_t; 29 30 30 31 /* ··· 64 63 extern void arm64_memblock_init(void); 65 64 extern void paging_init(void); 66 65 extern void bootmem_init(void); 67 - extern void __iomem *early_io_map(phys_addr_t phys, unsigned long virt); 68 66 extern void create_mapping_noalloc(phys_addr_t phys, unsigned long virt, 69 67 phys_addr_t size, pgprot_t prot); 70 68 extern void create_pgd_mapping(struct mm_struct *mm, phys_addr_t phys,
+45 -1
arch/arm64/include/asm/mmu_context.h
··· 15 15 #include <linux/sched/hotplug.h> 16 16 #include <linux/mm_types.h> 17 17 #include <linux/pgtable.h> 18 + #include <linux/pkeys.h> 18 19 19 20 #include <asm/cacheflush.h> 20 21 #include <asm/cpufeature.h> 21 22 #include <asm/daifflags.h> 22 23 #include <asm/proc-fns.h> 23 - #include <asm-generic/mm_hooks.h> 24 24 #include <asm/cputype.h> 25 25 #include <asm/sysreg.h> 26 26 #include <asm/tlbflush.h> ··· 175 175 { 176 176 atomic64_set(&mm->context.id, 0); 177 177 refcount_set(&mm->context.pinned, 0); 178 + 179 + /* pkey 0 is the default, so always reserve it. */ 180 + mm->context.pkey_allocation_map = BIT(0); 181 + 178 182 return 0; 183 + } 184 + 185 + static inline void arch_dup_pkeys(struct mm_struct *oldmm, 186 + struct mm_struct *mm) 187 + { 188 + /* Duplicate the oldmm pkey state in mm: */ 189 + mm->context.pkey_allocation_map = oldmm->context.pkey_allocation_map; 190 + } 191 + 192 + static inline int arch_dup_mmap(struct mm_struct *oldmm, struct mm_struct *mm) 193 + { 194 + arch_dup_pkeys(oldmm, mm); 195 + 196 + return 0; 197 + } 198 + 199 + static inline void arch_exit_mmap(struct mm_struct *mm) 200 + { 201 + } 202 + 203 + static inline void arch_unmap(struct mm_struct *mm, 204 + unsigned long start, unsigned long end) 205 + { 179 206 } 180 207 181 208 #ifdef CONFIG_ARM64_SW_TTBR0_PAN ··· 292 265 static inline unsigned long mm_untag_mask(struct mm_struct *mm) 293 266 { 294 267 return -1UL >> 8; 268 + } 269 + 270 + /* 271 + * Only enforce protection keys on the current process, because there is no 272 + * user context to access POR_EL0 for another address space. 273 + */ 274 + static inline bool arch_vma_access_permitted(struct vm_area_struct *vma, 275 + bool write, bool execute, bool foreign) 276 + { 277 + if (!system_supports_poe()) 278 + return true; 279 + 280 + /* allow access if the VMA is not one from this process */ 281 + if (foreign || vma_is_foreign(vma)) 282 + return true; 283 + 284 + return por_el0_allows_pkey(vma_pkey(vma), write, execute); 295 285 } 296 286 297 287 #include <asm-generic/mmu_context.h>
+10 -1
arch/arm64/include/asm/pgtable-hwdef.h
··· 135 135 /* 136 136 * Section 137 137 */ 138 - #define PMD_SECT_VALID (_AT(pmdval_t, 1) << 0) 139 138 #define PMD_SECT_USER (_AT(pmdval_t, 1) << 6) /* AP[1] */ 140 139 #define PMD_SECT_RDONLY (_AT(pmdval_t, 1) << 7) /* AP[2] */ 141 140 #define PMD_SECT_S (_AT(pmdval_t, 3) << 8) ··· 197 198 #define PTE_PI_IDX_1 51 /* DBM */ 198 199 #define PTE_PI_IDX_2 53 /* PXN */ 199 200 #define PTE_PI_IDX_3 54 /* UXN */ 201 + 202 + /* 203 + * POIndex[2:0] encoding (Permission Overlay Extension) 204 + */ 205 + #define PTE_PO_IDX_0 (_AT(pteval_t, 1) << 60) 206 + #define PTE_PO_IDX_1 (_AT(pteval_t, 1) << 61) 207 + #define PTE_PO_IDX_2 (_AT(pteval_t, 1) << 62) 208 + 209 + #define PTE_PO_IDX_MASK GENMASK_ULL(62, 60) 210 + 200 211 201 212 /* 202 213 * Memory Attribute override for Stage-2 (MemAttr[3:0])
+4 -4
arch/arm64/include/asm/pgtable-prot.h
··· 154 154 155 155 #define PIE_E0 ( \ 156 156 PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY), PIE_X_O) | \ 157 - PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_RX) | \ 158 - PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC), PIE_RWX) | \ 159 - PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY), PIE_R) | \ 160 - PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED), PIE_RW)) 157 + PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY_EXEC), PIE_RX_O) | \ 158 + PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED_EXEC), PIE_RWX_O) | \ 159 + PIRx_ELx_PERM(pte_pi_index(_PAGE_READONLY), PIE_R_O) | \ 160 + PIRx_ELx_PERM(pte_pi_index(_PAGE_SHARED), PIE_RW_O)) 161 161 162 162 #define PIE_E1 ( \ 163 163 PIRx_ELx_PERM(pte_pi_index(_PAGE_EXECONLY), PIE_NONE_O) | \
+29 -5
arch/arm64/include/asm/pgtable.h
··· 34 34 35 35 #include <asm/cmpxchg.h> 36 36 #include <asm/fixmap.h> 37 + #include <asm/por.h> 37 38 #include <linux/mmdebug.h> 38 39 #include <linux/mm_types.h> 39 40 #include <linux/sched.h> ··· 150 149 #define pte_accessible(mm, pte) \ 151 150 (mm_tlb_flush_pending(mm) ? pte_present(pte) : pte_valid(pte)) 152 151 152 + static inline bool por_el0_allows_pkey(u8 pkey, bool write, bool execute) 153 + { 154 + u64 por; 155 + 156 + if (!system_supports_poe()) 157 + return true; 158 + 159 + por = read_sysreg_s(SYS_POR_EL0); 160 + 161 + if (write) 162 + return por_elx_allows_write(por, pkey); 163 + 164 + if (execute) 165 + return por_elx_allows_exec(por, pkey); 166 + 167 + return por_elx_allows_read(por, pkey); 168 + } 169 + 153 170 /* 154 171 * p??_access_permitted() is true for valid user mappings (PTE_USER 155 172 * bit set, subject to the write permission check). For execute-only ··· 175 156 * not set) must return false. PROT_NONE mappings do not have the 176 157 * PTE_VALID bit set. 177 158 */ 178 - #define pte_access_permitted(pte, write) \ 159 + #define pte_access_permitted_no_overlay(pte, write) \ 179 160 (((pte_val(pte) & (PTE_VALID | PTE_USER)) == (PTE_VALID | PTE_USER)) && (!(write) || pte_write(pte))) 161 + #define pte_access_permitted(pte, write) \ 162 + (pte_access_permitted_no_overlay(pte, write) && \ 163 + por_el0_allows_pkey(FIELD_GET(PTE_PO_IDX_MASK, pte_val(pte)), write, false)) 180 164 #define pmd_access_permitted(pmd, write) \ 181 165 (pte_access_permitted(pmd_pte(pmd), (write))) 182 166 #define pud_access_permitted(pud, write) \ ··· 395 373 /* 396 374 * If the PTE would provide user space access to the tags associated 397 375 * with it then ensure that the MTE tags are synchronised. Although 398 - * pte_access_permitted() returns false for exec only mappings, they 399 - * don't expose tags (instruction fetches don't check tags). 376 + * pte_access_permitted_no_overlay() returns false for exec only 377 + * mappings, they don't expose tags (instruction fetches don't check 378 + * tags). 400 379 */ 401 - if (system_supports_mte() && pte_access_permitted(pte, false) && 380 + if (system_supports_mte() && pte_access_permitted_no_overlay(pte, false) && 402 381 !pte_special(pte) && pte_tagged(pte)) 403 382 mte_sync_tags(pte, nr_pages); 404 383 } ··· 1126 1103 */ 1127 1104 const pteval_t mask = PTE_USER | PTE_PXN | PTE_UXN | PTE_RDONLY | 1128 1105 PTE_PRESENT_INVALID | PTE_VALID | PTE_WRITE | 1129 - PTE_GP | PTE_ATTRINDX_MASK; 1106 + PTE_GP | PTE_ATTRINDX_MASK | PTE_PO_IDX_MASK; 1107 + 1130 1108 /* preserve the hardware dirty information */ 1131 1109 if (pte_hw_dirty(pte)) 1132 1110 pte = set_pte_bit(pte, __pgprot(PTE_DIRTY));
+106
arch/arm64/include/asm/pkeys.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2023 Arm Ltd. 4 + * 5 + * Based on arch/x86/include/asm/pkeys.h 6 + */ 7 + 8 + #ifndef _ASM_ARM64_PKEYS_H 9 + #define _ASM_ARM64_PKEYS_H 10 + 11 + #define ARCH_VM_PKEY_FLAGS (VM_PKEY_BIT0 | VM_PKEY_BIT1 | VM_PKEY_BIT2) 12 + 13 + #define arch_max_pkey() 8 14 + 15 + int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, 16 + unsigned long init_val); 17 + 18 + static inline bool arch_pkeys_enabled(void) 19 + { 20 + return system_supports_poe(); 21 + } 22 + 23 + static inline int vma_pkey(struct vm_area_struct *vma) 24 + { 25 + return (vma->vm_flags & ARCH_VM_PKEY_FLAGS) >> VM_PKEY_SHIFT; 26 + } 27 + 28 + static inline int arch_override_mprotect_pkey(struct vm_area_struct *vma, 29 + int prot, int pkey) 30 + { 31 + if (pkey != -1) 32 + return pkey; 33 + 34 + return vma_pkey(vma); 35 + } 36 + 37 + static inline int execute_only_pkey(struct mm_struct *mm) 38 + { 39 + // Execute-only mappings are handled by EPAN/FEAT_PAN3. 40 + return -1; 41 + } 42 + 43 + #define mm_pkey_allocation_map(mm) (mm)->context.pkey_allocation_map 44 + #define mm_set_pkey_allocated(mm, pkey) do { \ 45 + mm_pkey_allocation_map(mm) |= (1U << pkey); \ 46 + } while (0) 47 + #define mm_set_pkey_free(mm, pkey) do { \ 48 + mm_pkey_allocation_map(mm) &= ~(1U << pkey); \ 49 + } while (0) 50 + 51 + static inline bool mm_pkey_is_allocated(struct mm_struct *mm, int pkey) 52 + { 53 + /* 54 + * "Allocated" pkeys are those that have been returned 55 + * from pkey_alloc() or pkey 0 which is allocated 56 + * implicitly when the mm is created. 57 + */ 58 + if (pkey < 0 || pkey >= arch_max_pkey()) 59 + return false; 60 + 61 + return mm_pkey_allocation_map(mm) & (1U << pkey); 62 + } 63 + 64 + /* 65 + * Returns a positive, 3-bit key on success, or -1 on failure. 66 + */ 67 + static inline int mm_pkey_alloc(struct mm_struct *mm) 68 + { 69 + /* 70 + * Note: this is the one and only place we make sure 71 + * that the pkey is valid as far as the hardware is 72 + * concerned. The rest of the kernel trusts that 73 + * only good, valid pkeys come out of here. 74 + */ 75 + u8 all_pkeys_mask = GENMASK(arch_max_pkey() - 1, 0); 76 + int ret; 77 + 78 + if (!arch_pkeys_enabled()) 79 + return -1; 80 + 81 + /* 82 + * Are we out of pkeys? We must handle this specially 83 + * because ffz() behavior is undefined if there are no 84 + * zeros. 85 + */ 86 + if (mm_pkey_allocation_map(mm) == all_pkeys_mask) 87 + return -1; 88 + 89 + ret = ffz(mm_pkey_allocation_map(mm)); 90 + 91 + mm_set_pkey_allocated(mm, ret); 92 + 93 + return ret; 94 + } 95 + 96 + static inline int mm_pkey_free(struct mm_struct *mm, int pkey) 97 + { 98 + if (!mm_pkey_is_allocated(mm, pkey)) 99 + return -EINVAL; 100 + 101 + mm_set_pkey_free(mm, pkey); 102 + 103 + return 0; 104 + } 105 + 106 + #endif /* _ASM_ARM64_PKEYS_H */
+33
arch/arm64/include/asm/por.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2023 Arm Ltd. 4 + */ 5 + 6 + #ifndef _ASM_ARM64_POR_H 7 + #define _ASM_ARM64_POR_H 8 + 9 + #define POR_BITS_PER_PKEY 4 10 + #define POR_ELx_IDX(por_elx, idx) (((por_elx) >> ((idx) * POR_BITS_PER_PKEY)) & 0xf) 11 + 12 + static inline bool por_elx_allows_read(u64 por, u8 pkey) 13 + { 14 + u8 perm = POR_ELx_IDX(por, pkey); 15 + 16 + return perm & POE_R; 17 + } 18 + 19 + static inline bool por_elx_allows_write(u64 por, u8 pkey) 20 + { 21 + u8 perm = POR_ELx_IDX(por, pkey); 22 + 23 + return perm & POE_W; 24 + } 25 + 26 + static inline bool por_elx_allows_exec(u64 por, u8 pkey) 27 + { 28 + u8 perm = POR_ELx_IDX(por, pkey); 29 + 30 + return perm & POE_X; 31 + } 32 + 33 + #endif /* _ASM_ARM64_POR_H */
+6
arch/arm64/include/asm/processor.h
··· 184 184 u64 sctlr_user; 185 185 u64 svcr; 186 186 u64 tpidr2_el0; 187 + u64 por_el0; 187 188 }; 188 189 189 190 static inline unsigned int thread_get_vl(struct thread_struct *thread, ··· 402 401 #define SET_TAGGED_ADDR_CTRL(arg) set_tagged_addr_ctrl(current, arg) 403 402 #define GET_TAGGED_ADDR_CTRL() get_tagged_addr_ctrl(current) 404 403 #endif 404 + 405 + int get_tsc_mode(unsigned long adr); 406 + int set_tsc_mode(unsigned int val); 407 + #define GET_TSC_CTL(adr) get_tsc_mode((adr)) 408 + #define SET_TSC_CTL(val) set_tsc_mode((val)) 405 409 406 410 #endif /* __ASSEMBLY__ */ 407 411 #endif /* __ASM_PROCESSOR_H */
+1
arch/arm64/include/asm/set_memory.h
··· 3 3 #ifndef _ASM_ARM64_SET_MEMORY_H 4 4 #define _ASM_ARM64_SET_MEMORY_H 5 5 6 + #include <asm/mem_encrypt.h> 6 7 #include <asm-generic/set_memory.h> 7 8 8 9 bool can_set_direct_map(void);
+3 -1
arch/arm64/include/asm/sysreg.h
··· 403 403 #define SYS_PMCNTENCLR_EL0 sys_reg(3, 3, 9, 12, 2) 404 404 #define SYS_PMOVSCLR_EL0 sys_reg(3, 3, 9, 12, 3) 405 405 #define SYS_PMSWINC_EL0 sys_reg(3, 3, 9, 12, 4) 406 - #define SYS_PMSELR_EL0 sys_reg(3, 3, 9, 12, 5) 407 406 #define SYS_PMCEID0_EL0 sys_reg(3, 3, 9, 12, 6) 408 407 #define SYS_PMCEID1_EL0 sys_reg(3, 3, 9, 12, 7) 409 408 #define SYS_PMCCNTR_EL0 sys_reg(3, 3, 9, 13, 0) ··· 1075 1076 #define POE_XW UL(0x6) 1076 1077 #define POE_RXW UL(0x7) 1077 1078 #define POE_MASK UL(0xf) 1079 + 1080 + /* Initial value for Permission Overlay Extension for EL0 */ 1081 + #define POR_EL0_INIT POE_RXW 1078 1082 1079 1083 #define ARM64_FEATURE_FIELD_BITS 4 1080 1084
+2
arch/arm64/include/asm/thread_info.h
··· 81 81 #define TIF_SME 27 /* SME in use */ 82 82 #define TIF_SME_VL_INHERIT 28 /* Inherit SME vl_onexec across exec */ 83 83 #define TIF_KERNEL_FPSTATE 29 /* Task is in a kernel mode FPSIMD section */ 84 + #define TIF_TSC_SIGSEGV 30 /* SIGSEGV on counter-timer access */ 84 85 85 86 #define _TIF_SIGPENDING (1 << TIF_SIGPENDING) 86 87 #define _TIF_NEED_RESCHED (1 << TIF_NEED_RESCHED) ··· 98 97 #define _TIF_SVE (1 << TIF_SVE) 99 98 #define _TIF_MTE_ASYNC_FAULT (1 << TIF_MTE_ASYNC_FAULT) 100 99 #define _TIF_NOTIFY_SIGNAL (1 << TIF_NOTIFY_SIGNAL) 100 + #define _TIF_TSC_SIGSEGV (1 << TIF_TSC_SIGSEGV) 101 101 102 102 #define _TIF_WORK_MASK (_TIF_NEED_RESCHED | _TIF_SIGPENDING | \ 103 103 _TIF_NOTIFY_RESUME | _TIF_FOREIGN_FPSTATE | \
+1
arch/arm64/include/asm/traps.h
··· 25 25 void force_signal_inject(int signal, int code, unsigned long address, unsigned long err); 26 26 void arm64_notify_segfault(unsigned long addr); 27 27 void arm64_force_sig_fault(int signo, int code, unsigned long far, const char *str); 28 + void arm64_force_sig_fault_pkey(unsigned long far, const char *str, int pkey); 28 29 void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, const char *str); 29 30 void arm64_force_sig_ptrace_errno_trap(int errno, unsigned long far, const char *str); 30 31
+1
arch/arm64/include/asm/vncr_mapping.h
··· 52 52 #define VNCR_PIRE0_EL1 0x290 53 53 #define VNCR_PIRE0_EL2 0x298 54 54 #define VNCR_PIR_EL1 0x2A0 55 + #define VNCR_POR_EL1 0x2A8 55 56 #define VNCR_ICH_LR0_EL2 0x400 56 57 #define VNCR_ICH_LR1_EL2 0x408 57 58 #define VNCR_ICH_LR2_EL2 0x410
+1
arch/arm64/include/uapi/asm/hwcap.h
··· 122 122 #define HWCAP2_SME_SF8FMA (1UL << 60) 123 123 #define HWCAP2_SME_SF8DP4 (1UL << 61) 124 124 #define HWCAP2_SME_SF8DP2 (1UL << 62) 125 + #define HWCAP2_POE (1UL << 63) 125 126 126 127 #endif /* _UAPI__ASM_HWCAP_H */
+9
arch/arm64/include/uapi/asm/mman.h
··· 7 7 #define PROT_BTI 0x10 /* BTI guarded page */ 8 8 #define PROT_MTE 0x20 /* Normal Tagged mapping */ 9 9 10 + /* Override any generic PKEY permission defines */ 11 + #define PKEY_DISABLE_EXECUTE 0x4 12 + #define PKEY_DISABLE_READ 0x8 13 + #undef PKEY_ACCESS_MASK 14 + #define PKEY_ACCESS_MASK (PKEY_DISABLE_ACCESS |\ 15 + PKEY_DISABLE_WRITE |\ 16 + PKEY_DISABLE_READ |\ 17 + PKEY_DISABLE_EXECUTE) 18 + 10 19 #endif /* ! _UAPI__ASM_MMAN_H */
+10 -3
arch/arm64/include/uapi/asm/sigcontext.h
··· 98 98 __u64 esr; 99 99 }; 100 100 101 + #define POE_MAGIC 0x504f4530 102 + 103 + struct poe_context { 104 + struct _aarch64_ctx head; 105 + __u64 por_el0; 106 + }; 107 + 101 108 /* 102 109 * extra_context: describes extra space in the signal frame for 103 110 * additional structures that don't fit in sigcontext.__reserved[]. ··· 327 320 ((sizeof(struct za_context) + (__SVE_VQ_BYTES - 1)) \ 328 321 / __SVE_VQ_BYTES * __SVE_VQ_BYTES) 329 322 330 - #define ZA_SIG_REGS_SIZE(vq) ((vq * __SVE_VQ_BYTES) * (vq * __SVE_VQ_BYTES)) 323 + #define ZA_SIG_REGS_SIZE(vq) (((vq) * __SVE_VQ_BYTES) * ((vq) * __SVE_VQ_BYTES)) 331 324 332 325 #define ZA_SIG_ZAV_OFFSET(vq, n) (ZA_SIG_REGS_OFFSET + \ 333 - (SVE_SIG_ZREG_SIZE(vq) * n)) 326 + (SVE_SIG_ZREG_SIZE(vq) * (n))) 334 327 335 328 #define ZA_SIG_CONTEXT_SIZE(vq) \ 336 329 (ZA_SIG_REGS_OFFSET + ZA_SIG_REGS_SIZE(vq)) ··· 341 334 342 335 #define ZT_SIG_REGS_OFFSET sizeof(struct zt_context) 343 336 344 - #define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * n) 337 + #define ZT_SIG_REGS_SIZE(n) (ZT_SIG_REG_BYTES * (n)) 345 338 346 339 #define ZT_SIG_CONTEXT_SIZE(n) \ 347 340 (sizeof(struct zt_context) + ZT_SIG_REGS_SIZE(n))
+9 -1
arch/arm64/kernel/cpu_errata.c
··· 456 456 }; 457 457 #endif 458 458 459 + #ifdef CONFIG_AMPERE_ERRATUM_AC03_CPU_38 460 + static const struct midr_range erratum_ac03_cpu_38_list[] = { 461 + MIDR_ALL_VERSIONS(MIDR_AMPERE1), 462 + MIDR_ALL_VERSIONS(MIDR_AMPERE1A), 463 + {}, 464 + }; 465 + #endif 466 + 459 467 const struct arm64_cpu_capabilities arm64_errata[] = { 460 468 #ifdef CONFIG_ARM64_WORKAROUND_CLEAN_CACHE 461 469 { ··· 780 772 { 781 773 .desc = "AmpereOne erratum AC03_CPU_38", 782 774 .capability = ARM64_WORKAROUND_AMPERE_AC03_CPU_38, 783 - ERRATA_MIDR_ALL_VERSIONS(MIDR_AMPERE1), 775 + ERRATA_MIDR_RANGE_LIST(erratum_ac03_cpu_38_list), 784 776 }, 785 777 #endif 786 778 {
+23
arch/arm64/kernel/cpufeature.c
··· 466 466 }; 467 467 468 468 static const struct arm64_ftr_bits ftr_id_aa64mmfr3[] = { 469 + ARM64_FTR_BITS(FTR_VISIBLE_IF_IS_ENABLED(CONFIG_ARM64_POE), 470 + FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_S1POE_SHIFT, 4, 0), 469 471 ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_S1PIE_SHIFT, 4, 0), 470 472 ARM64_FTR_BITS(FTR_HIDDEN, FTR_NONSTRICT, FTR_LOWER_SAFE, ID_AA64MMFR3_EL1_TCRX_SHIFT, 4, 0), 471 473 ARM64_FTR_END, ··· 2350 2348 sysreg_clear_set(sctlr_el1, 0, SCTLR_EL1_MSCEn); 2351 2349 } 2352 2350 2351 + #ifdef CONFIG_ARM64_POE 2352 + static void cpu_enable_poe(const struct arm64_cpu_capabilities *__unused) 2353 + { 2354 + sysreg_clear_set(REG_TCR2_EL1, 0, TCR2_EL1x_E0POE); 2355 + sysreg_clear_set(CPACR_EL1, 0, CPACR_ELx_E0POE); 2356 + } 2357 + #endif 2358 + 2353 2359 /* Internal helper functions to match cpu capability type */ 2354 2360 static bool 2355 2361 cpucap_late_cpu_optional(const struct arm64_cpu_capabilities *cap) ··· 2880 2870 .matches = has_nv1, 2881 2871 ARM64_CPUID_FIELDS_NEG(ID_AA64MMFR4_EL1, E2H0, NI_NV1) 2882 2872 }, 2873 + #ifdef CONFIG_ARM64_POE 2874 + { 2875 + .desc = "Stage-1 Permission Overlay Extension (S1POE)", 2876 + .capability = ARM64_HAS_S1POE, 2877 + .type = ARM64_CPUCAP_BOOT_CPU_FEATURE, 2878 + .matches = has_cpuid_feature, 2879 + .cpu_enable = cpu_enable_poe, 2880 + ARM64_CPUID_FIELDS(ID_AA64MMFR3_EL1, S1POE, IMP) 2881 + }, 2882 + #endif 2883 2883 {}, 2884 2884 }; 2885 2885 ··· 3054 3034 HWCAP_CAP(ID_AA64FPFR0_EL1, F8DP2, IMP, CAP_HWCAP, KERNEL_HWCAP_F8DP2), 3055 3035 HWCAP_CAP(ID_AA64FPFR0_EL1, F8E4M3, IMP, CAP_HWCAP, KERNEL_HWCAP_F8E4M3), 3056 3036 HWCAP_CAP(ID_AA64FPFR0_EL1, F8E5M2, IMP, CAP_HWCAP, KERNEL_HWCAP_F8E5M2), 3037 + #ifdef CONFIG_ARM64_POE 3038 + HWCAP_CAP(ID_AA64MMFR3_EL1, S1POE, IMP, CAP_HWCAP, KERNEL_HWCAP_POE), 3039 + #endif 3057 3040 {}, 3058 3041 }; 3059 3042
+2 -1
arch/arm64/kernel/cpuinfo.c
··· 143 143 [KERNEL_HWCAP_SME_SF8FMA] = "smesf8fma", 144 144 [KERNEL_HWCAP_SME_SF8DP4] = "smesf8dp4", 145 145 [KERNEL_HWCAP_SME_SF8DP2] = "smesf8dp2", 146 + [KERNEL_HWCAP_POE] = "poe", 146 147 }; 147 148 148 149 #ifdef CONFIG_COMPAT ··· 281 280 }; 282 281 283 282 284 - static struct kobj_type cpuregs_kobj_type = { 283 + static const struct kobj_type cpuregs_kobj_type = { 285 284 .sysfs_ops = &kobj_sysfs_ops, 286 285 }; 287 286
+1 -1
arch/arm64/kernel/hibernate.c
··· 407 407 void *, phys_addr_t, phys_addr_t); 408 408 struct trans_pgd_info trans_info = { 409 409 .trans_alloc_page = hibernate_page_alloc, 410 - .trans_alloc_arg = (void *)GFP_ATOMIC, 410 + .trans_alloc_arg = (__force void *)GFP_ATOMIC, 411 411 }; 412 412 413 413 /*
+85 -12
arch/arm64/kernel/process.c
··· 43 43 #include <linux/stacktrace.h> 44 44 45 45 #include <asm/alternative.h> 46 + #include <asm/arch_timer.h> 46 47 #include <asm/compat.h> 47 48 #include <asm/cpufeature.h> 48 49 #include <asm/cacheflush.h> ··· 272 271 clear_thread_flag(TIF_TAGGED_ADDR); 273 272 } 274 273 274 + static void flush_poe(void) 275 + { 276 + if (!system_supports_poe()) 277 + return; 278 + 279 + write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0); 280 + } 281 + 275 282 void flush_thread(void) 276 283 { 277 284 fpsimd_flush_thread(); 278 285 tls_thread_flush(); 279 286 flush_ptrace_hw_breakpoint(current); 280 287 flush_tagged_addr_state(); 288 + flush_poe(); 281 289 } 282 290 283 291 void arch_release_task_struct(struct task_struct *tsk) ··· 380 370 *task_user_tls(p) = read_sysreg(tpidr_el0); 381 371 if (system_supports_tpidr2()) 382 372 p->thread.tpidr2_el0 = read_sysreg_s(SYS_TPIDR2_EL0); 373 + 374 + if (system_supports_poe()) 375 + p->thread.por_el0 = read_sysreg_s(SYS_POR_EL0); 383 376 384 377 if (stack_start) { 385 378 if (is_compat_thread(task_thread_info(p))) ··· 485 472 } 486 473 487 474 /* 488 - * ARM erratum 1418040 handling, affecting the 32bit view of CNTVCT. 489 - * Ensure access is disabled when switching to a 32bit task, ensure 490 - * access is enabled when switching to a 64bit task. 475 + * Handle sysreg updates for ARM erratum 1418040 which affects the 32bit view of 476 + * CNTVCT, various other errata which require trapping all CNTVCT{,_EL0} 477 + * accesses and prctl(PR_SET_TSC). Ensure access is disabled iff a workaround is 478 + * required or PR_TSC_SIGSEGV is set. 491 479 */ 492 - static void erratum_1418040_thread_switch(struct task_struct *next) 480 + static void update_cntkctl_el1(struct task_struct *next) 493 481 { 494 - if (!IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040) || 495 - !this_cpu_has_cap(ARM64_WORKAROUND_1418040)) 496 - return; 482 + struct thread_info *ti = task_thread_info(next); 497 483 498 - if (is_compat_thread(task_thread_info(next))) 484 + if (test_ti_thread_flag(ti, TIF_TSC_SIGSEGV) || 485 + has_erratum_handler(read_cntvct_el0) || 486 + (IS_ENABLED(CONFIG_ARM64_ERRATUM_1418040) && 487 + this_cpu_has_cap(ARM64_WORKAROUND_1418040) && 488 + is_compat_thread(ti))) 499 489 sysreg_clear_set(cntkctl_el1, ARCH_TIMER_USR_VCT_ACCESS_EN, 0); 500 490 else 501 491 sysreg_clear_set(cntkctl_el1, 0, ARCH_TIMER_USR_VCT_ACCESS_EN); 502 492 } 503 493 504 - static void erratum_1418040_new_exec(void) 494 + static void cntkctl_thread_switch(struct task_struct *prev, 495 + struct task_struct *next) 505 496 { 497 + if ((read_ti_thread_flags(task_thread_info(prev)) & 498 + (_TIF_32BIT | _TIF_TSC_SIGSEGV)) != 499 + (read_ti_thread_flags(task_thread_info(next)) & 500 + (_TIF_32BIT | _TIF_TSC_SIGSEGV))) 501 + update_cntkctl_el1(next); 502 + } 503 + 504 + static int do_set_tsc_mode(unsigned int val) 505 + { 506 + bool tsc_sigsegv; 507 + 508 + if (val == PR_TSC_SIGSEGV) 509 + tsc_sigsegv = true; 510 + else if (val == PR_TSC_ENABLE) 511 + tsc_sigsegv = false; 512 + else 513 + return -EINVAL; 514 + 506 515 preempt_disable(); 507 - erratum_1418040_thread_switch(current); 516 + update_thread_flag(TIF_TSC_SIGSEGV, tsc_sigsegv); 517 + update_cntkctl_el1(current); 508 518 preempt_enable(); 519 + 520 + return 0; 521 + } 522 + 523 + static void permission_overlay_switch(struct task_struct *next) 524 + { 525 + if (!system_supports_poe()) 526 + return; 527 + 528 + current->thread.por_el0 = read_sysreg_s(SYS_POR_EL0); 529 + if (current->thread.por_el0 != next->thread.por_el0) { 530 + write_sysreg_s(next->thread.por_el0, SYS_POR_EL0); 531 + } 509 532 } 510 533 511 534 /* ··· 577 528 contextidr_thread_switch(next); 578 529 entry_task_switch(next); 579 530 ssbs_thread_switch(next); 580 - erratum_1418040_thread_switch(next); 531 + cntkctl_thread_switch(prev, next); 581 532 ptrauth_thread_switch_user(next); 533 + permission_overlay_switch(next); 582 534 583 535 /* 584 536 * Complete any pending TLB or cache maintenance on this CPU in case ··· 695 645 current->mm->context.flags = mmflags; 696 646 ptrauth_thread_init_user(); 697 647 mte_thread_init_user(); 698 - erratum_1418040_new_exec(); 648 + do_set_tsc_mode(PR_TSC_ENABLE); 699 649 700 650 if (task_spec_ssb_noexec(current)) { 701 651 arch_prctl_spec_ctrl_set(current, PR_SPEC_STORE_BYPASS, ··· 804 754 return prot; 805 755 } 806 756 #endif 757 + 758 + int get_tsc_mode(unsigned long adr) 759 + { 760 + unsigned int val; 761 + 762 + if (is_compat_task()) 763 + return -EINVAL; 764 + 765 + if (test_thread_flag(TIF_TSC_SIGSEGV)) 766 + val = PR_TSC_SIGSEGV; 767 + else 768 + val = PR_TSC_ENABLE; 769 + 770 + return put_user(val, (unsigned int __user *)adr); 771 + } 772 + 773 + int set_tsc_mode(unsigned int val) 774 + { 775 + if (is_compat_task()) 776 + return -EINVAL; 777 + 778 + return do_set_tsc_mode(val); 779 + }
+46
arch/arm64/kernel/ptrace.c
··· 1440 1440 } 1441 1441 #endif 1442 1442 1443 + #ifdef CONFIG_ARM64_POE 1444 + static int poe_get(struct task_struct *target, 1445 + const struct user_regset *regset, 1446 + struct membuf to) 1447 + { 1448 + if (!system_supports_poe()) 1449 + return -EINVAL; 1450 + 1451 + return membuf_write(&to, &target->thread.por_el0, 1452 + sizeof(target->thread.por_el0)); 1453 + } 1454 + 1455 + static int poe_set(struct task_struct *target, const struct 1456 + user_regset *regset, unsigned int pos, 1457 + unsigned int count, const void *kbuf, const 1458 + void __user *ubuf) 1459 + { 1460 + int ret; 1461 + long ctrl; 1462 + 1463 + if (!system_supports_poe()) 1464 + return -EINVAL; 1465 + 1466 + ret = user_regset_copyin(&pos, &count, &kbuf, &ubuf, &ctrl, 0, -1); 1467 + if (ret) 1468 + return ret; 1469 + 1470 + target->thread.por_el0 = ctrl; 1471 + 1472 + return 0; 1473 + } 1474 + #endif 1475 + 1443 1476 enum aarch64_regset { 1444 1477 REGSET_GPR, 1445 1478 REGSET_FPR, ··· 1501 1468 #endif 1502 1469 #ifdef CONFIG_ARM64_TAGGED_ADDR_ABI 1503 1470 REGSET_TAGGED_ADDR_CTRL, 1471 + #endif 1472 + #ifdef CONFIG_ARM64_POE 1473 + REGSET_POE 1504 1474 #endif 1505 1475 }; 1506 1476 ··· 1662 1626 .align = sizeof(long), 1663 1627 .regset_get = tagged_addr_ctrl_get, 1664 1628 .set = tagged_addr_ctrl_set, 1629 + }, 1630 + #endif 1631 + #ifdef CONFIG_ARM64_POE 1632 + [REGSET_POE] = { 1633 + .core_note_type = NT_ARM_POE, 1634 + .n = 1, 1635 + .size = sizeof(long), 1636 + .align = sizeof(long), 1637 + .regset_get = poe_get, 1638 + .set = poe_set, 1665 1639 }, 1666 1640 #endif 1667 1641 };
+62
arch/arm64/kernel/signal.c
··· 61 61 unsigned long za_offset; 62 62 unsigned long zt_offset; 63 63 unsigned long fpmr_offset; 64 + unsigned long poe_offset; 64 65 unsigned long extra_offset; 65 66 unsigned long end_offset; 66 67 }; ··· 186 185 u32 zt_size; 187 186 struct fpmr_context __user *fpmr; 188 187 u32 fpmr_size; 188 + struct poe_context __user *poe; 189 + u32 poe_size; 189 190 }; 190 191 191 192 static int preserve_fpsimd_context(struct fpsimd_context __user *ctx) ··· 257 254 __get_user_error(fpmr, &user->fpmr->fpmr, err); 258 255 if (!err) 259 256 write_sysreg_s(fpmr, SYS_FPMR); 257 + 258 + return err; 259 + } 260 + 261 + static int preserve_poe_context(struct poe_context __user *ctx) 262 + { 263 + int err = 0; 264 + 265 + __put_user_error(POE_MAGIC, &ctx->head.magic, err); 266 + __put_user_error(sizeof(*ctx), &ctx->head.size, err); 267 + __put_user_error(read_sysreg_s(SYS_POR_EL0), &ctx->por_el0, err); 268 + 269 + return err; 270 + } 271 + 272 + static int restore_poe_context(struct user_ctxs *user) 273 + { 274 + u64 por_el0; 275 + int err = 0; 276 + 277 + if (user->poe_size != sizeof(*user->poe)) 278 + return -EINVAL; 279 + 280 + __get_user_error(por_el0, &(user->poe->por_el0), err); 281 + if (!err) 282 + write_sysreg_s(por_el0, SYS_POR_EL0); 260 283 261 284 return err; 262 285 } ··· 650 621 user->za = NULL; 651 622 user->zt = NULL; 652 623 user->fpmr = NULL; 624 + user->poe = NULL; 653 625 654 626 if (!IS_ALIGNED((unsigned long)base, 16)) 655 627 goto invalid; ··· 699 669 700 670 case ESR_MAGIC: 701 671 /* ignore */ 672 + break; 673 + 674 + case POE_MAGIC: 675 + if (!system_supports_poe()) 676 + goto invalid; 677 + 678 + if (user->poe) 679 + goto invalid; 680 + 681 + user->poe = (struct poe_context __user *)head; 682 + user->poe_size = size; 702 683 break; 703 684 704 685 case SVE_MAGIC: ··· 898 857 if (err == 0 && system_supports_sme2() && user.zt) 899 858 err = restore_zt_context(&user); 900 859 860 + if (err == 0 && system_supports_poe() && user.poe) 861 + err = restore_poe_context(&user); 862 + 901 863 return err; 902 864 } 903 865 ··· 1024 980 return err; 1025 981 } 1026 982 983 + if (system_supports_poe()) { 984 + err = sigframe_alloc(user, &user->poe_offset, 985 + sizeof(struct poe_context)); 986 + if (err) 987 + return err; 988 + } 989 + 1027 990 return sigframe_alloc_end(user); 1028 991 } 1029 992 ··· 1092 1041 apply_user_offset(user, user->fpmr_offset); 1093 1042 err |= preserve_fpmr_context(fpmr_ctx); 1094 1043 } 1044 + 1045 + if (system_supports_poe() && err == 0 && user->poe_offset) { 1046 + struct poe_context __user *poe_ctx = 1047 + apply_user_offset(user, user->poe_offset); 1048 + 1049 + err |= preserve_poe_context(poe_ctx); 1050 + } 1051 + 1095 1052 1096 1053 /* ZA state if present */ 1097 1054 if (system_supports_sme() && err == 0 && user->za_offset) { ··· 1236 1177 SVCR_SM_MASK); 1237 1178 sme_smstop(); 1238 1179 } 1180 + 1181 + if (system_supports_poe()) 1182 + write_sysreg_s(POR_EL0_INIT, SYS_POR_EL0); 1239 1183 1240 1184 if (ka->sa.sa_flags & SA_RESTORER) 1241 1185 sigtramp = ka->sa.sa_restorer;
+99 -65
arch/arm64/kernel/smp.c
··· 68 68 IPI_RESCHEDULE, 69 69 IPI_CALL_FUNC, 70 70 IPI_CPU_STOP, 71 - IPI_CPU_CRASH_STOP, 71 + IPI_CPU_STOP_NMI, 72 72 IPI_TIMER, 73 73 IPI_IRQ_WORK, 74 74 NR_IPI, ··· 84 84 static int ipi_irq_base __ro_after_init; 85 85 static int nr_ipi __ro_after_init = NR_IPI; 86 86 static struct irq_desc *ipi_desc[MAX_IPI] __ro_after_init; 87 + 88 + static bool crash_stop; 87 89 88 90 static void ipi_setup(int cpu); 89 91 ··· 825 823 [IPI_RESCHEDULE] = "Rescheduling interrupts", 826 824 [IPI_CALL_FUNC] = "Function call interrupts", 827 825 [IPI_CPU_STOP] = "CPU stop interrupts", 828 - [IPI_CPU_CRASH_STOP] = "CPU stop (for crash dump) interrupts", 826 + [IPI_CPU_STOP_NMI] = "CPU stop NMIs", 829 827 [IPI_TIMER] = "Timer broadcast interrupts", 830 828 [IPI_IRQ_WORK] = "IRQ work interrupts", 831 829 [IPI_CPU_BACKTRACE] = "CPU backtrace interrupts", ··· 869 867 } 870 868 #endif 871 869 872 - static void __noreturn local_cpu_stop(void) 870 + static void __noreturn local_cpu_stop(unsigned int cpu) 873 871 { 874 - set_cpu_online(smp_processor_id(), false); 872 + set_cpu_online(cpu, false); 875 873 876 874 local_daif_mask(); 877 875 sdei_mask_local_cpu(); ··· 885 883 */ 886 884 void __noreturn panic_smp_self_stop(void) 887 885 { 888 - local_cpu_stop(); 886 + local_cpu_stop(smp_processor_id()); 889 887 } 890 - 891 - #ifdef CONFIG_KEXEC_CORE 892 - static atomic_t waiting_for_crash_ipi = ATOMIC_INIT(0); 893 - #endif 894 888 895 889 static void __noreturn ipi_cpu_crash_stop(unsigned int cpu, struct pt_regs *regs) 896 890 { 897 891 #ifdef CONFIG_KEXEC_CORE 892 + /* 893 + * Use local_daif_mask() instead of local_irq_disable() to make sure 894 + * that pseudo-NMIs are disabled. The "crash stop" code starts with 895 + * an IRQ and falls back to NMI (which might be pseudo). If the IRQ 896 + * finally goes through right as we're timing out then the NMI could 897 + * interrupt us. It's better to prevent the NMI and let the IRQ 898 + * finish since the pt_regs will be better. 899 + */ 900 + local_daif_mask(); 901 + 898 902 crash_save_cpu(regs, cpu); 899 903 900 - atomic_dec(&waiting_for_crash_ipi); 904 + set_cpu_online(cpu, false); 901 905 902 - local_irq_disable(); 903 906 sdei_mask_local_cpu(); 904 907 905 908 if (IS_ENABLED(CONFIG_HOTPLUG_CPU)) ··· 969 962 break; 970 963 971 964 case IPI_CPU_STOP: 972 - local_cpu_stop(); 973 - break; 974 - 975 - case IPI_CPU_CRASH_STOP: 976 - if (IS_ENABLED(CONFIG_KEXEC_CORE)) { 965 + case IPI_CPU_STOP_NMI: 966 + if (IS_ENABLED(CONFIG_KEXEC_CORE) && crash_stop) { 977 967 ipi_cpu_crash_stop(cpu, get_irq_regs()); 978 - 979 968 unreachable(); 969 + } else { 970 + local_cpu_stop(cpu); 980 971 } 981 972 break; 982 973 ··· 1029 1024 return false; 1030 1025 1031 1026 switch (ipi) { 1032 - case IPI_CPU_STOP: 1033 - case IPI_CPU_CRASH_STOP: 1027 + case IPI_CPU_STOP_NMI: 1034 1028 case IPI_CPU_BACKTRACE: 1035 1029 case IPI_KGDB_ROUNDUP: 1036 1030 return true; ··· 1142 1138 1143 1139 void smp_send_stop(void) 1144 1140 { 1145 - unsigned long timeout; 1146 - 1147 - if (num_other_online_cpus()) { 1148 - cpumask_t mask; 1149 - 1150 - cpumask_copy(&mask, cpu_online_mask); 1151 - cpumask_clear_cpu(smp_processor_id(), &mask); 1152 - 1153 - if (system_state <= SYSTEM_RUNNING) 1154 - pr_crit("SMP: stopping secondary CPUs\n"); 1155 - smp_cross_call(&mask, IPI_CPU_STOP); 1156 - } 1157 - 1158 - /* Wait up to one second for other CPUs to stop */ 1159 - timeout = USEC_PER_SEC; 1160 - while (num_other_online_cpus() && timeout--) 1161 - udelay(1); 1162 - 1163 - if (num_other_online_cpus()) 1164 - pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", 1165 - cpumask_pr_args(cpu_online_mask)); 1166 - 1167 - sdei_mask_local_cpu(); 1168 - } 1169 - 1170 - #ifdef CONFIG_KEXEC_CORE 1171 - void crash_smp_send_stop(void) 1172 - { 1173 - static int cpus_stopped; 1141 + static unsigned long stop_in_progress; 1174 1142 cpumask_t mask; 1175 1143 unsigned long timeout; 1176 - 1177 - /* 1178 - * This function can be called twice in panic path, but obviously 1179 - * we execute this only once. 1180 - */ 1181 - if (cpus_stopped) 1182 - return; 1183 - 1184 - cpus_stopped = 1; 1185 1144 1186 1145 /* 1187 1146 * If this cpu is the only one alive at this point in time, online or ··· 1153 1186 if (num_other_online_cpus() == 0) 1154 1187 goto skip_ipi; 1155 1188 1189 + /* Only proceed if this is the first CPU to reach this code */ 1190 + if (test_and_set_bit(0, &stop_in_progress)) 1191 + return; 1192 + 1193 + /* 1194 + * Send an IPI to all currently online CPUs except the CPU running 1195 + * this code. 1196 + * 1197 + * NOTE: we don't do anything here to prevent other CPUs from coming 1198 + * online after we snapshot `cpu_online_mask`. Ideally, the calling code 1199 + * should do something to prevent other CPUs from coming up. This code 1200 + * can be called in the panic path and thus it doesn't seem wise to 1201 + * grab the CPU hotplug mutex ourselves. Worst case: 1202 + * - If a CPU comes online as we're running, we'll likely notice it 1203 + * during the 1 second wait below and then we'll catch it when we try 1204 + * with an NMI (assuming NMIs are enabled) since we re-snapshot the 1205 + * mask before sending an NMI. 1206 + * - If we leave the function and see that CPUs are still online we'll 1207 + * at least print a warning. Especially without NMIs this function 1208 + * isn't foolproof anyway so calling code will just have to accept 1209 + * the fact that there could be cases where a CPU can't be stopped. 1210 + */ 1156 1211 cpumask_copy(&mask, cpu_online_mask); 1157 1212 cpumask_clear_cpu(smp_processor_id(), &mask); 1158 1213 1159 - atomic_set(&waiting_for_crash_ipi, num_other_online_cpus()); 1214 + if (system_state <= SYSTEM_RUNNING) 1215 + pr_crit("SMP: stopping secondary CPUs\n"); 1160 1216 1161 - pr_crit("SMP: stopping secondary CPUs\n"); 1162 - smp_cross_call(&mask, IPI_CPU_CRASH_STOP); 1163 - 1164 - /* Wait up to one second for other CPUs to stop */ 1217 + /* 1218 + * Start with a normal IPI and wait up to one second for other CPUs to 1219 + * stop. We do this first because it gives other processors a chance 1220 + * to exit critical sections / drop locks and makes the rest of the 1221 + * stop process (especially console flush) more robust. 1222 + */ 1223 + smp_cross_call(&mask, IPI_CPU_STOP); 1165 1224 timeout = USEC_PER_SEC; 1166 - while ((atomic_read(&waiting_for_crash_ipi) > 0) && timeout--) 1225 + while (num_other_online_cpus() && timeout--) 1167 1226 udelay(1); 1168 1227 1169 - if (atomic_read(&waiting_for_crash_ipi) > 0) 1228 + /* 1229 + * If CPUs are still online, try an NMI. There's no excuse for this to 1230 + * be slow, so we only give them an extra 10 ms to respond. 1231 + */ 1232 + if (num_other_online_cpus() && ipi_should_be_nmi(IPI_CPU_STOP_NMI)) { 1233 + smp_rmb(); 1234 + cpumask_copy(&mask, cpu_online_mask); 1235 + cpumask_clear_cpu(smp_processor_id(), &mask); 1236 + 1237 + pr_info("SMP: retry stop with NMI for CPUs %*pbl\n", 1238 + cpumask_pr_args(&mask)); 1239 + 1240 + smp_cross_call(&mask, IPI_CPU_STOP_NMI); 1241 + timeout = USEC_PER_MSEC * 10; 1242 + while (num_other_online_cpus() && timeout--) 1243 + udelay(1); 1244 + } 1245 + 1246 + if (num_other_online_cpus()) { 1247 + smp_rmb(); 1248 + cpumask_copy(&mask, cpu_online_mask); 1249 + cpumask_clear_cpu(smp_processor_id(), &mask); 1250 + 1170 1251 pr_warn("SMP: failed to stop secondary CPUs %*pbl\n", 1171 1252 cpumask_pr_args(&mask)); 1253 + } 1172 1254 1173 1255 skip_ipi: 1174 1256 sdei_mask_local_cpu(); 1257 + } 1258 + 1259 + #ifdef CONFIG_KEXEC_CORE 1260 + void crash_smp_send_stop(void) 1261 + { 1262 + /* 1263 + * This function can be called twice in panic path, but obviously 1264 + * we execute this only once. 1265 + * 1266 + * We use this same boolean to tell whether the IPI we send was a 1267 + * stop or a "crash stop". 1268 + */ 1269 + if (crash_stop) 1270 + return; 1271 + crash_stop = 1; 1272 + 1273 + smp_send_stop(); 1274 + 1175 1275 sdei_handler_abort(); 1176 1276 } 1177 1277 1178 1278 bool smp_crash_stop_failed(void) 1179 1279 { 1180 - return (atomic_read(&waiting_for_crash_ipi) > 0); 1280 + return num_other_online_cpus() != 0; 1181 1281 } 1182 1282 #endif 1183 1283
+20 -6
arch/arm64/kernel/traps.c
··· 273 273 force_sig_fault(signo, code, (void __user *)far); 274 274 } 275 275 276 + void arm64_force_sig_fault_pkey(unsigned long far, const char *str, int pkey) 277 + { 278 + arm64_show_signal(SIGSEGV, str); 279 + force_sig_pkuerr((void __user *)far, pkey); 280 + } 281 + 276 282 void arm64_force_sig_mceerr(int code, unsigned long far, short lsb, 277 283 const char *str) 278 284 { ··· 607 601 608 602 static void cntvct_read_handler(unsigned long esr, struct pt_regs *regs) 609 603 { 610 - int rt = ESR_ELx_SYS64_ISS_RT(esr); 604 + if (test_thread_flag(TIF_TSC_SIGSEGV)) { 605 + force_sig(SIGSEGV); 606 + } else { 607 + int rt = ESR_ELx_SYS64_ISS_RT(esr); 611 608 612 - pt_regs_write_reg(regs, rt, arch_timer_read_counter()); 613 - arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); 609 + pt_regs_write_reg(regs, rt, arch_timer_read_counter()); 610 + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); 611 + } 614 612 } 615 613 616 614 static void cntfrq_read_handler(unsigned long esr, struct pt_regs *regs) 617 615 { 618 - int rt = ESR_ELx_SYS64_ISS_RT(esr); 616 + if (test_thread_flag(TIF_TSC_SIGSEGV)) { 617 + force_sig(SIGSEGV); 618 + } else { 619 + int rt = ESR_ELx_SYS64_ISS_RT(esr); 619 620 620 - pt_regs_write_reg(regs, rt, arch_timer_get_rate()); 621 - arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); 621 + pt_regs_write_reg(regs, rt, arch_timer_get_rate()); 622 + arm64_skip_faulting_instruction(regs, AARCH64_INSN_SIZE); 623 + } 622 624 } 623 625 624 626 static void mrs_handler(unsigned long esr, struct pt_regs *regs)
+4 -1
arch/arm64/kvm/hyp/include/hyp/fault.h
··· 14 14 15 15 static inline bool __translate_far_to_hpfar(u64 far, u64 *hpfar) 16 16 { 17 + int ret; 17 18 u64 par, tmp; 18 19 19 20 /* ··· 28 27 * saved the guest context yet, and we may return early... 29 28 */ 30 29 par = read_sysreg_par(); 31 - if (!__kvm_at("s1e1r", far)) 30 + ret = system_supports_poe() ? __kvm_at(OP_AT_S1E1A, far) : 31 + __kvm_at(OP_AT_S1E1R, far); 32 + if (!ret) 32 33 tmp = read_sysreg_par(); 33 34 else 34 35 tmp = SYS_PAR_EL1_F; /* back to the guest */
+27
arch/arm64/kvm/hyp/include/hyp/sysreg-sr.h
··· 16 16 #include <asm/kvm_hyp.h> 17 17 #include <asm/kvm_mmu.h> 18 18 19 + static inline bool ctxt_has_s1poe(struct kvm_cpu_context *ctxt); 20 + 19 21 static inline void __sysreg_save_common_state(struct kvm_cpu_context *ctxt) 20 22 { 21 23 ctxt_sys_reg(ctxt, MDSCR_EL1) = read_sysreg(mdscr_el1); 24 + 25 + // POR_EL0 can affect uaccess, so must be saved/restored early. 26 + if (ctxt_has_s1poe(ctxt)) 27 + ctxt_sys_reg(ctxt, POR_EL0) = read_sysreg_s(SYS_POR_EL0); 22 28 } 23 29 24 30 static inline void __sysreg_save_user_state(struct kvm_cpu_context *ctxt) ··· 72 66 return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, TCRX, IMP); 73 67 } 74 68 69 + static inline bool ctxt_has_s1poe(struct kvm_cpu_context *ctxt) 70 + { 71 + struct kvm_vcpu *vcpu; 72 + 73 + if (!system_supports_poe()) 74 + return false; 75 + 76 + vcpu = ctxt_to_vcpu(ctxt); 77 + return kvm_has_feat(kern_hyp_va(vcpu->kvm), ID_AA64MMFR3_EL1, S1POE, IMP); 78 + } 79 + 75 80 static inline void __sysreg_save_el1_state(struct kvm_cpu_context *ctxt) 76 81 { 77 82 ctxt_sys_reg(ctxt, SCTLR_EL1) = read_sysreg_el1(SYS_SCTLR); ··· 97 80 ctxt_sys_reg(ctxt, PIR_EL1) = read_sysreg_el1(SYS_PIR); 98 81 ctxt_sys_reg(ctxt, PIRE0_EL1) = read_sysreg_el1(SYS_PIRE0); 99 82 } 83 + 84 + if (ctxt_has_s1poe(ctxt)) 85 + ctxt_sys_reg(ctxt, POR_EL1) = read_sysreg_el1(SYS_POR); 100 86 } 101 87 ctxt_sys_reg(ctxt, ESR_EL1) = read_sysreg_el1(SYS_ESR); 102 88 ctxt_sys_reg(ctxt, AFSR0_EL1) = read_sysreg_el1(SYS_AFSR0); ··· 140 120 static inline void __sysreg_restore_common_state(struct kvm_cpu_context *ctxt) 141 121 { 142 122 write_sysreg(ctxt_sys_reg(ctxt, MDSCR_EL1), mdscr_el1); 123 + 124 + // POR_EL0 can affect uaccess, so must be saved/restored early. 125 + if (ctxt_has_s1poe(ctxt)) 126 + write_sysreg_s(ctxt_sys_reg(ctxt, POR_EL0), SYS_POR_EL0); 143 127 } 144 128 145 129 static inline void __sysreg_restore_user_state(struct kvm_cpu_context *ctxt) ··· 182 158 write_sysreg_el1(ctxt_sys_reg(ctxt, PIR_EL1), SYS_PIR); 183 159 write_sysreg_el1(ctxt_sys_reg(ctxt, PIRE0_EL1), SYS_PIRE0); 184 160 } 161 + 162 + if (ctxt_has_s1poe(ctxt)) 163 + write_sysreg_el1(ctxt_sys_reg(ctxt, POR_EL1), SYS_POR); 185 164 } 186 165 write_sysreg_el1(ctxt_sys_reg(ctxt, ESR_EL1), SYS_ESR); 187 166 write_sysreg_el1(ctxt_sys_reg(ctxt, AFSR0_EL1), SYS_AFSR0);
+7 -7
arch/arm64/kvm/pmu-emul.c
··· 233 233 int i; 234 234 struct kvm_pmu *pmu = &vcpu->arch.pmu; 235 235 236 - for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) 236 + for (i = 0; i < KVM_ARMV8_PMU_MAX_COUNTERS; i++) 237 237 pmu->pmc[i].idx = i; 238 238 } 239 239 ··· 260 260 { 261 261 int i; 262 262 263 - for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) 263 + for (i = 0; i < KVM_ARMV8_PMU_MAX_COUNTERS; i++) 264 264 kvm_pmu_release_perf_event(kvm_vcpu_idx_to_pmc(vcpu, i)); 265 265 irq_work_sync(&vcpu->arch.pmu.overflow_work); 266 266 } ··· 291 291 if (!(kvm_vcpu_read_pmcr(vcpu) & ARMV8_PMU_PMCR_E) || !val) 292 292 return; 293 293 294 - for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { 294 + for (i = 0; i < KVM_ARMV8_PMU_MAX_COUNTERS; i++) { 295 295 struct kvm_pmc *pmc; 296 296 297 297 if (!(val & BIT(i))) ··· 323 323 if (!kvm_vcpu_has_pmu(vcpu) || !val) 324 324 return; 325 325 326 - for (i = 0; i < ARMV8_PMU_MAX_COUNTERS; i++) { 326 + for (i = 0; i < KVM_ARMV8_PMU_MAX_COUNTERS; i++) { 327 327 struct kvm_pmc *pmc; 328 328 329 329 if (!(val & BIT(i))) ··· 910 910 struct arm_pmu *arm_pmu = kvm->arch.arm_pmu; 911 911 912 912 /* 913 - * The arm_pmu->num_events considers the cycle counter as well. 914 - * Ignore that and return only the general-purpose counters. 913 + * The arm_pmu->cntr_mask considers the fixed counter(s) as well. 914 + * Ignore those and return only the general-purpose counters. 915 915 */ 916 - return arm_pmu->num_events - 1; 916 + return bitmap_weight(arm_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS); 917 917 } 918 918 919 919 static void kvm_arm_set_pmu(struct kvm *kvm, struct arm_pmu *arm_pmu)
+21 -66
arch/arm64/kvm/pmu.c
··· 5 5 */ 6 6 #include <linux/kvm_host.h> 7 7 #include <linux/perf_event.h> 8 + #include <linux/perf/arm_pmu.h> 9 + #include <linux/perf/arm_pmuv3.h> 8 10 9 11 static DEFINE_PER_CPU(struct kvm_pmu_events, kvm_pmu_events); 10 12 ··· 37 35 * Add events to track that we may want to switch at guest entry/exit 38 36 * time. 39 37 */ 40 - void kvm_set_pmu_events(u32 set, struct perf_event_attr *attr) 38 + void kvm_set_pmu_events(u64 set, struct perf_event_attr *attr) 41 39 { 42 40 struct kvm_pmu_events *pmu = kvm_get_pmu_events(); 43 41 ··· 53 51 /* 54 52 * Stop tracking events 55 53 */ 56 - void kvm_clr_pmu_events(u32 clr) 54 + void kvm_clr_pmu_events(u64 clr) 57 55 { 58 56 struct kvm_pmu_events *pmu = kvm_get_pmu_events(); 59 57 ··· 64 62 pmu->events_guest &= ~clr; 65 63 } 66 64 67 - #define PMEVTYPER_READ_CASE(idx) \ 68 - case idx: \ 69 - return read_sysreg(pmevtyper##idx##_el0) 70 - 71 - #define PMEVTYPER_WRITE_CASE(idx) \ 72 - case idx: \ 73 - write_sysreg(val, pmevtyper##idx##_el0); \ 74 - break 75 - 76 - #define PMEVTYPER_CASES(readwrite) \ 77 - PMEVTYPER_##readwrite##_CASE(0); \ 78 - PMEVTYPER_##readwrite##_CASE(1); \ 79 - PMEVTYPER_##readwrite##_CASE(2); \ 80 - PMEVTYPER_##readwrite##_CASE(3); \ 81 - PMEVTYPER_##readwrite##_CASE(4); \ 82 - PMEVTYPER_##readwrite##_CASE(5); \ 83 - PMEVTYPER_##readwrite##_CASE(6); \ 84 - PMEVTYPER_##readwrite##_CASE(7); \ 85 - PMEVTYPER_##readwrite##_CASE(8); \ 86 - PMEVTYPER_##readwrite##_CASE(9); \ 87 - PMEVTYPER_##readwrite##_CASE(10); \ 88 - PMEVTYPER_##readwrite##_CASE(11); \ 89 - PMEVTYPER_##readwrite##_CASE(12); \ 90 - PMEVTYPER_##readwrite##_CASE(13); \ 91 - PMEVTYPER_##readwrite##_CASE(14); \ 92 - PMEVTYPER_##readwrite##_CASE(15); \ 93 - PMEVTYPER_##readwrite##_CASE(16); \ 94 - PMEVTYPER_##readwrite##_CASE(17); \ 95 - PMEVTYPER_##readwrite##_CASE(18); \ 96 - PMEVTYPER_##readwrite##_CASE(19); \ 97 - PMEVTYPER_##readwrite##_CASE(20); \ 98 - PMEVTYPER_##readwrite##_CASE(21); \ 99 - PMEVTYPER_##readwrite##_CASE(22); \ 100 - PMEVTYPER_##readwrite##_CASE(23); \ 101 - PMEVTYPER_##readwrite##_CASE(24); \ 102 - PMEVTYPER_##readwrite##_CASE(25); \ 103 - PMEVTYPER_##readwrite##_CASE(26); \ 104 - PMEVTYPER_##readwrite##_CASE(27); \ 105 - PMEVTYPER_##readwrite##_CASE(28); \ 106 - PMEVTYPER_##readwrite##_CASE(29); \ 107 - PMEVTYPER_##readwrite##_CASE(30) 108 - 109 65 /* 110 66 * Read a value direct from PMEVTYPER<idx> where idx is 0-30 111 - * or PMCCFILTR_EL0 where idx is ARMV8_PMU_CYCLE_IDX (31). 67 + * or PMxCFILTR_EL0 where idx is 31-32. 112 68 */ 113 69 static u64 kvm_vcpu_pmu_read_evtype_direct(int idx) 114 70 { 115 - switch (idx) { 116 - PMEVTYPER_CASES(READ); 117 - case ARMV8_PMU_CYCLE_IDX: 118 - return read_sysreg(pmccfiltr_el0); 119 - default: 120 - WARN_ON(1); 121 - } 71 + if (idx == ARMV8_PMU_CYCLE_IDX) 72 + return read_pmccfiltr(); 73 + else if (idx == ARMV8_PMU_INSTR_IDX) 74 + return read_pmicfiltr(); 122 75 123 - return 0; 76 + return read_pmevtypern(idx); 124 77 } 125 78 126 79 /* 127 80 * Write a value direct to PMEVTYPER<idx> where idx is 0-30 128 - * or PMCCFILTR_EL0 where idx is ARMV8_PMU_CYCLE_IDX (31). 81 + * or PMxCFILTR_EL0 where idx is 31-32. 129 82 */ 130 83 static void kvm_vcpu_pmu_write_evtype_direct(int idx, u32 val) 131 84 { 132 - switch (idx) { 133 - PMEVTYPER_CASES(WRITE); 134 - case ARMV8_PMU_CYCLE_IDX: 135 - write_sysreg(val, pmccfiltr_el0); 136 - break; 137 - default: 138 - WARN_ON(1); 139 - } 85 + if (idx == ARMV8_PMU_CYCLE_IDX) 86 + write_pmccfiltr(val); 87 + else if (idx == ARMV8_PMU_INSTR_IDX) 88 + write_pmicfiltr(val); 89 + else 90 + write_pmevtypern(idx, val); 140 91 } 141 92 142 93 /* ··· 100 145 u64 typer; 101 146 u32 counter; 102 147 103 - for_each_set_bit(counter, &events, 32) { 148 + for_each_set_bit(counter, &events, ARMPMU_MAX_HWEVENTS) { 104 149 typer = kvm_vcpu_pmu_read_evtype_direct(counter); 105 150 typer &= ~ARMV8_PMU_EXCLUDE_EL0; 106 151 kvm_vcpu_pmu_write_evtype_direct(counter, typer); ··· 115 160 u64 typer; 116 161 u32 counter; 117 162 118 - for_each_set_bit(counter, &events, 32) { 163 + for_each_set_bit(counter, &events, ARMPMU_MAX_HWEVENTS) { 119 164 typer = kvm_vcpu_pmu_read_evtype_direct(counter); 120 165 typer |= ARMV8_PMU_EXCLUDE_EL0; 121 166 kvm_vcpu_pmu_write_evtype_direct(counter, typer); ··· 131 176 void kvm_vcpu_pmu_restore_guest(struct kvm_vcpu *vcpu) 132 177 { 133 178 struct kvm_pmu_events *pmu; 134 - u32 events_guest, events_host; 179 + u64 events_guest, events_host; 135 180 136 181 if (!kvm_arm_support_pmu_v3() || !has_vhe()) 137 182 return; ··· 152 197 void kvm_vcpu_pmu_restore_host(struct kvm_vcpu *vcpu) 153 198 { 154 199 struct kvm_pmu_events *pmu; 155 - u32 events_guest, events_host; 200 + u64 events_guest, events_host; 156 201 157 202 if (!kvm_arm_support_pmu_v3() || !has_vhe()) 158 203 return;
+28 -8
arch/arm64/kvm/sys_regs.c
··· 18 18 #include <linux/printk.h> 19 19 #include <linux/uaccess.h> 20 20 21 + #include <asm/arm_pmuv3.h> 21 22 #include <asm/cacheflush.h> 22 23 #include <asm/cputype.h> 23 24 #include <asm/debug-monitors.h> ··· 894 893 static u64 reset_pmselr(struct kvm_vcpu *vcpu, const struct sys_reg_desc *r) 895 894 { 896 895 reset_unknown(vcpu, r); 897 - __vcpu_sys_reg(vcpu, r->reg) &= ARMV8_PMU_COUNTER_MASK; 896 + __vcpu_sys_reg(vcpu, r->reg) &= PMSELR_EL0_SEL_MASK; 898 897 899 898 return __vcpu_sys_reg(vcpu, r->reg); 900 899 } ··· 986 985 else 987 986 /* return PMSELR.SEL field */ 988 987 p->regval = __vcpu_sys_reg(vcpu, PMSELR_EL0) 989 - & ARMV8_PMU_COUNTER_MASK; 988 + & PMSELR_EL0_SEL_MASK; 990 989 991 990 return true; 992 991 } ··· 1054 1053 if (pmu_access_event_counter_el0_disabled(vcpu)) 1055 1054 return false; 1056 1055 1057 - idx = __vcpu_sys_reg(vcpu, PMSELR_EL0) 1058 - & ARMV8_PMU_COUNTER_MASK; 1056 + idx = SYS_FIELD_GET(PMSELR_EL0, SEL, 1057 + __vcpu_sys_reg(vcpu, PMSELR_EL0)); 1059 1058 } else if (r->Op2 == 0) { 1060 1059 /* PMCCNTR_EL0 */ 1061 1060 if (pmu_access_cycle_counter_el0_disabled(vcpu)) ··· 1105 1104 1106 1105 if (r->CRn == 9 && r->CRm == 13 && r->Op2 == 1) { 1107 1106 /* PMXEVTYPER_EL0 */ 1108 - idx = __vcpu_sys_reg(vcpu, PMSELR_EL0) & ARMV8_PMU_COUNTER_MASK; 1107 + idx = SYS_FIELD_GET(PMSELR_EL0, SEL, __vcpu_sys_reg(vcpu, PMSELR_EL0)); 1109 1108 reg = PMEVTYPER0_EL0 + idx; 1110 1109 } else if (r->CRn == 14 && (r->CRm & 12) == 12) { 1111 1110 idx = ((r->CRm & 3) << 3) | (r->Op2 & 7); ··· 1562 1561 break; 1563 1562 case SYS_ID_AA64MMFR2_EL1: 1564 1563 val &= ~ID_AA64MMFR2_EL1_CCIDX_MASK; 1564 + break; 1565 + case SYS_ID_AA64MMFR3_EL1: 1566 + val &= ID_AA64MMFR3_EL1_TCRX | ID_AA64MMFR3_EL1_S1POE; 1565 1567 break; 1566 1568 case SYS_ID_MMFR4_EL1: 1567 1569 val &= ~ARM64_FEATURE_MASK(ID_MMFR4_EL1_CCIDX); ··· 2265 2261 return true; 2266 2262 } 2267 2263 2264 + static unsigned int s1poe_visibility(const struct kvm_vcpu *vcpu, 2265 + const struct sys_reg_desc *rd) 2266 + { 2267 + if (kvm_has_feat(vcpu->kvm, ID_AA64MMFR3_EL1, S1POE, IMP)) 2268 + return 0; 2269 + 2270 + return REG_HIDDEN; 2271 + } 2272 + 2268 2273 /* 2269 2274 * Architected system registers. 2270 2275 * Important: Must be sorted ascending by Op0, Op1, CRn, CRm, Op2 ··· 2437 2424 ID_AA64MMFR2_EL1_IDS | 2438 2425 ID_AA64MMFR2_EL1_NV | 2439 2426 ID_AA64MMFR2_EL1_CCIDX)), 2440 - ID_SANITISED(ID_AA64MMFR3_EL1), 2427 + ID_WRITABLE(ID_AA64MMFR3_EL1, (ID_AA64MMFR3_EL1_TCRX | 2428 + ID_AA64MMFR3_EL1_S1POE)), 2441 2429 ID_SANITISED(ID_AA64MMFR4_EL1), 2442 2430 ID_UNALLOCATED(7,5), 2443 2431 ID_UNALLOCATED(7,6), ··· 2512 2498 { SYS_DESC(SYS_MAIR_EL1), access_vm_reg, reset_unknown, MAIR_EL1 }, 2513 2499 { SYS_DESC(SYS_PIRE0_EL1), NULL, reset_unknown, PIRE0_EL1 }, 2514 2500 { SYS_DESC(SYS_PIR_EL1), NULL, reset_unknown, PIR_EL1 }, 2501 + { SYS_DESC(SYS_POR_EL1), NULL, reset_unknown, POR_EL1, 2502 + .visibility = s1poe_visibility }, 2515 2503 { SYS_DESC(SYS_AMAIR_EL1), access_vm_reg, reset_amair_el1, AMAIR_EL1 }, 2516 2504 2517 2505 { SYS_DESC(SYS_LORSA_EL1), trap_loregion }, ··· 2600 2584 .access = access_pmovs, .reg = PMOVSSET_EL0, 2601 2585 .get_user = get_pmreg, .set_user = set_pmreg }, 2602 2586 2587 + { SYS_DESC(SYS_POR_EL0), NULL, reset_unknown, POR_EL0, 2588 + .visibility = s1poe_visibility }, 2603 2589 { SYS_DESC(SYS_TPIDR_EL0), NULL, reset_unknown, TPIDR_EL0 }, 2604 2590 { SYS_DESC(SYS_TPIDRRO_EL0), NULL, reset_unknown, TPIDRRO_EL0 }, 2605 2591 { SYS_DESC(SYS_TPIDR2_EL0), undef_access }, ··· 4592 4574 kvm->arch.fgu[HFGxTR_GROUP] = (HFGxTR_EL2_nAMAIR2_EL1 | 4593 4575 HFGxTR_EL2_nMAIR2_EL1 | 4594 4576 HFGxTR_EL2_nS2POR_EL1 | 4595 - HFGxTR_EL2_nPOR_EL1 | 4596 - HFGxTR_EL2_nPOR_EL0 | 4597 4577 HFGxTR_EL2_nACCDATA_EL1 | 4598 4578 HFGxTR_EL2_nSMPRI_EL1_MASK | 4599 4579 HFGxTR_EL2_nTPIDR2_EL0_MASK); ··· 4625 4609 if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1PIE, IMP)) 4626 4610 kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPIRE0_EL1 | 4627 4611 HFGxTR_EL2_nPIR_EL1); 4612 + 4613 + if (!kvm_has_feat(kvm, ID_AA64MMFR3_EL1, S1POE, IMP)) 4614 + kvm->arch.fgu[HFGxTR_GROUP] |= (HFGxTR_EL2_nPOR_EL1 | 4615 + HFGxTR_EL2_nPOR_EL0); 4628 4616 4629 4617 if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP)) 4630 4618 kvm->arch.fgu[HAFGRTR_GROUP] |= ~(HAFGRTR_EL2_RES0 |
+1 -1
arch/arm64/mm/Makefile
··· 1 1 # SPDX-License-Identifier: GPL-2.0 2 2 obj-y := dma-mapping.o extable.o fault.o init.o \ 3 3 cache.o copypage.o flush.o \ 4 - ioremap.o mmap.o pgd.o mmu.o \ 4 + ioremap.o mmap.o pgd.o mem_encrypt.o mmu.o \ 5 5 context.o proc.o pageattr.o fixmap.o 6 6 obj-$(CONFIG_ARM64_CONTPTE) += contpte.o 7 7 obj-$(CONFIG_HUGETLB_PAGE) += hugetlbpage.o
+6
arch/arm64/mm/contpte.c
··· 421 421 ptep = contpte_align_down(ptep); 422 422 start_addr = addr = ALIGN_DOWN(addr, CONT_PTE_SIZE); 423 423 424 + /* 425 + * We are not advancing entry because __ptep_set_access_flags() 426 + * only consumes access flags from entry. And since we have checked 427 + * for the whole contpte block and returned early, pte_same() 428 + * within __ptep_set_access_flags() is likely false. 429 + */ 424 430 for (i = 0; i < CONT_PTES; i++, ptep++, addr += PAGE_SIZE) 425 431 __ptep_set_access_flags(vma, addr, ptep, entry, 0); 426 432
+54 -1
arch/arm64/mm/fault.c
··· 23 23 #include <linux/sched/debug.h> 24 24 #include <linux/highmem.h> 25 25 #include <linux/perf_event.h> 26 + #include <linux/pkeys.h> 26 27 #include <linux/preempt.h> 27 28 #include <linux/hugetlb.h> 28 29 ··· 487 486 } 488 487 } 489 488 489 + static bool fault_from_pkey(unsigned long esr, struct vm_area_struct *vma, 490 + unsigned int mm_flags) 491 + { 492 + unsigned long iss2 = ESR_ELx_ISS2(esr); 493 + 494 + if (!system_supports_poe()) 495 + return false; 496 + 497 + if (esr_fsc_is_permission_fault(esr) && (iss2 & ESR_ELx_Overlay)) 498 + return true; 499 + 500 + return !arch_vma_access_permitted(vma, 501 + mm_flags & FAULT_FLAG_WRITE, 502 + mm_flags & FAULT_FLAG_INSTRUCTION, 503 + false); 504 + } 505 + 490 506 static bool is_el0_instruction_abort(unsigned long esr) 491 507 { 492 508 return ESR_ELx_EC(esr) == ESR_ELx_EC_IABT_LOW; ··· 529 511 unsigned long addr = untagged_addr(far); 530 512 struct vm_area_struct *vma; 531 513 int si_code; 514 + int pkey = -1; 532 515 533 516 if (kprobe_page_fault(regs, esr)) 534 517 return 0; ··· 594 575 count_vm_vma_lock_event(VMA_LOCK_SUCCESS); 595 576 goto bad_area; 596 577 } 578 + 579 + if (fault_from_pkey(esr, vma, mm_flags)) { 580 + pkey = vma_pkey(vma); 581 + vma_end_read(vma); 582 + fault = 0; 583 + si_code = SEGV_PKUERR; 584 + count_vm_vma_lock_event(VMA_LOCK_SUCCESS); 585 + goto bad_area; 586 + } 587 + 597 588 fault = handle_mm_fault(vma, addr, mm_flags | FAULT_FLAG_VMA_LOCK, regs); 598 589 if (!(fault & (VM_FAULT_RETRY | VM_FAULT_COMPLETED))) 599 590 vma_end_read(vma); ··· 639 610 goto bad_area; 640 611 } 641 612 613 + if (fault_from_pkey(esr, vma, mm_flags)) { 614 + pkey = vma_pkey(vma); 615 + mmap_read_unlock(mm); 616 + fault = 0; 617 + si_code = SEGV_PKUERR; 618 + goto bad_area; 619 + } 620 + 642 621 fault = handle_mm_fault(vma, addr, mm_flags, regs); 622 + 643 623 /* Quick path to respond to signals */ 644 624 if (fault_signal_pending(fault, regs)) { 645 625 if (!user_mode(regs)) ··· 707 669 708 670 arm64_force_sig_mceerr(BUS_MCEERR_AR, far, lsb, inf->name); 709 671 } else { 672 + /* 673 + * The pkey value that we return to userspace can be different 674 + * from the pkey that caused the fault. 675 + * 676 + * 1. T1 : mprotect_key(foo, PAGE_SIZE, pkey=4); 677 + * 2. T1 : set POR_EL0 to deny access to pkey=4, touches, page 678 + * 3. T1 : faults... 679 + * 4. T2: mprotect_key(foo, PAGE_SIZE, pkey=5); 680 + * 5. T1 : enters fault handler, takes mmap_lock, etc... 681 + * 6. T1 : reaches here, sees vma_pkey(vma)=5, when we really 682 + * faulted on a pte with its pkey=4. 683 + */ 710 684 /* Something tried to access memory that out of memory map */ 711 - arm64_force_sig_fault(SIGSEGV, si_code, far, inf->name); 685 + if (si_code == SEGV_PKUERR) 686 + arm64_force_sig_fault_pkey(far, inf->name, pkey); 687 + else 688 + arm64_force_sig_fault(SIGSEGV, si_code, far, inf->name); 712 689 } 713 690 714 691 return 0;
+10 -2
arch/arm64/mm/init.c
··· 414 414 415 415 void free_initmem(void) 416 416 { 417 - free_reserved_area(lm_alias(__init_begin), 418 - lm_alias(__init_end), 417 + void *lm_init_begin = lm_alias(__init_begin); 418 + void *lm_init_end = lm_alias(__init_end); 419 + 420 + WARN_ON(!IS_ALIGNED((unsigned long)lm_init_begin, PAGE_SIZE)); 421 + WARN_ON(!IS_ALIGNED((unsigned long)lm_init_end, PAGE_SIZE)); 422 + 423 + /* Delete __init region from memblock.reserved. */ 424 + memblock_free(lm_init_begin, lm_init_end - lm_init_begin); 425 + 426 + free_reserved_area(lm_init_begin, lm_init_end, 419 427 POISON_FREE_INITMEM, "unused kernel"); 420 428 /* 421 429 * Unmap the __init region but leave the VM area in place. This
+22 -1
arch/arm64/mm/ioremap.c
··· 3 3 #include <linux/mm.h> 4 4 #include <linux/io.h> 5 5 6 + static ioremap_prot_hook_t ioremap_prot_hook; 7 + 8 + int arm64_ioremap_prot_hook_register(ioremap_prot_hook_t hook) 9 + { 10 + if (WARN_ON(ioremap_prot_hook)) 11 + return -EBUSY; 12 + 13 + ioremap_prot_hook = hook; 14 + return 0; 15 + } 16 + 6 17 void __iomem *ioremap_prot(phys_addr_t phys_addr, size_t size, 7 18 unsigned long prot) 8 19 { 9 20 unsigned long last_addr = phys_addr + size - 1; 21 + pgprot_t pgprot = __pgprot(prot); 10 22 11 23 /* Don't allow outside PHYS_MASK */ 12 24 if (last_addr & ~PHYS_MASK) ··· 28 16 if (WARN_ON(pfn_is_map_memory(__phys_to_pfn(phys_addr)))) 29 17 return NULL; 30 18 31 - return generic_ioremap_prot(phys_addr, size, __pgprot(prot)); 19 + /* 20 + * If a hook is registered (e.g. for confidential computing 21 + * purposes), call that now and barf if it fails. 22 + */ 23 + if (unlikely(ioremap_prot_hook) && 24 + WARN_ON(ioremap_prot_hook(phys_addr, size, &pgprot))) { 25 + return NULL; 26 + } 27 + 28 + return generic_ioremap_prot(phys_addr, size, pgprot); 32 29 } 33 30 EXPORT_SYMBOL(ioremap_prot); 34 31
+50
arch/arm64/mm/mem_encrypt.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Implementation of the memory encryption/decryption API. 4 + * 5 + * Since the low-level details of the operation depend on the 6 + * Confidential Computing environment (e.g. pKVM, CCA, ...), this just 7 + * acts as a top-level dispatcher to whatever hooks may have been 8 + * registered. 9 + * 10 + * Author: Will Deacon <will@kernel.org> 11 + * Copyright (C) 2024 Google LLC 12 + * 13 + * "Hello, boils and ghouls!" 14 + */ 15 + 16 + #include <linux/bug.h> 17 + #include <linux/compiler.h> 18 + #include <linux/err.h> 19 + #include <linux/mm.h> 20 + 21 + #include <asm/mem_encrypt.h> 22 + 23 + static const struct arm64_mem_crypt_ops *crypt_ops; 24 + 25 + int arm64_mem_crypt_ops_register(const struct arm64_mem_crypt_ops *ops) 26 + { 27 + if (WARN_ON(crypt_ops)) 28 + return -EBUSY; 29 + 30 + crypt_ops = ops; 31 + return 0; 32 + } 33 + 34 + int set_memory_encrypted(unsigned long addr, int numpages) 35 + { 36 + if (likely(!crypt_ops) || WARN_ON(!PAGE_ALIGNED(addr))) 37 + return 0; 38 + 39 + return crypt_ops->encrypt(addr, numpages); 40 + } 41 + EXPORT_SYMBOL_GPL(set_memory_encrypted); 42 + 43 + int set_memory_decrypted(unsigned long addr, int numpages) 44 + { 45 + if (likely(!crypt_ops) || WARN_ON(!PAGE_ALIGNED(addr))) 46 + return 0; 47 + 48 + return crypt_ops->decrypt(addr, numpages); 49 + } 50 + EXPORT_SYMBOL_GPL(set_memory_decrypted);
+11
arch/arm64/mm/mmap.c
··· 102 102 if (vm_flags & VM_MTE) 103 103 prot |= PTE_ATTRINDX(MT_NORMAL_TAGGED); 104 104 105 + #ifdef CONFIG_ARCH_HAS_PKEYS 106 + if (system_supports_poe()) { 107 + if (vm_flags & VM_PKEY_BIT0) 108 + prot |= PTE_PO_IDX_0; 109 + if (vm_flags & VM_PKEY_BIT1) 110 + prot |= PTE_PO_IDX_1; 111 + if (vm_flags & VM_PKEY_BIT2) 112 + prot |= PTE_PO_IDX_2; 113 + } 114 + #endif 115 + 105 116 return __pgprot(prot); 106 117 } 107 118 EXPORT_SYMBOL(vm_get_page_prot);
+45
arch/arm64/mm/mmu.c
··· 25 25 #include <linux/vmalloc.h> 26 26 #include <linux/set_memory.h> 27 27 #include <linux/kfence.h> 28 + #include <linux/pkeys.h> 28 29 29 30 #include <asm/barrier.h> 30 31 #include <asm/cputype.h> ··· 1550 1549 1551 1550 cpu_uninstall_idmap(); 1552 1551 } 1552 + 1553 + #ifdef CONFIG_ARCH_HAS_PKEYS 1554 + int arch_set_user_pkey_access(struct task_struct *tsk, int pkey, unsigned long init_val) 1555 + { 1556 + u64 new_por = POE_RXW; 1557 + u64 old_por; 1558 + u64 pkey_shift; 1559 + 1560 + if (!system_supports_poe()) 1561 + return -ENOSPC; 1562 + 1563 + /* 1564 + * This code should only be called with valid 'pkey' 1565 + * values originating from in-kernel users. Complain 1566 + * if a bad value is observed. 1567 + */ 1568 + if (WARN_ON_ONCE(pkey >= arch_max_pkey())) 1569 + return -EINVAL; 1570 + 1571 + /* Set the bits we need in POR: */ 1572 + new_por = POE_RXW; 1573 + if (init_val & PKEY_DISABLE_WRITE) 1574 + new_por &= ~POE_W; 1575 + if (init_val & PKEY_DISABLE_ACCESS) 1576 + new_por &= ~POE_RW; 1577 + if (init_val & PKEY_DISABLE_READ) 1578 + new_por &= ~POE_R; 1579 + if (init_val & PKEY_DISABLE_EXECUTE) 1580 + new_por &= ~POE_X; 1581 + 1582 + /* Shift the bits in to the correct place in POR for pkey: */ 1583 + pkey_shift = pkey * POR_BITS_PER_PKEY; 1584 + new_por <<= pkey_shift; 1585 + 1586 + /* Get old POR and mask off any old bits in place: */ 1587 + old_por = read_sysreg_s(SYS_POR_EL0); 1588 + old_por &= ~(POE_MASK << pkey_shift); 1589 + 1590 + /* Write old part along with new part: */ 1591 + write_sysreg_s(old_por | new_por, SYS_POR_EL0); 1592 + 1593 + return 0; 1594 + } 1595 + #endif
+1 -3
arch/arm64/mm/proc.S
··· 36 36 #define TCR_KASLR_FLAGS 0 37 37 #endif 38 38 39 - #define TCR_SMP_FLAGS TCR_SHARED 40 - 41 39 /* PTWs cacheable, inner/outer WBWA */ 42 40 #define TCR_CACHE_FLAGS TCR_IRGN_WBWA | TCR_ORGN_WBWA 43 41 ··· 467 469 tcr .req x16 468 470 mov_q mair, MAIR_EL1_SET 469 471 mov_q tcr, TCR_T0SZ(IDMAP_VA_BITS) | TCR_T1SZ(VA_BITS_MIN) | TCR_CACHE_FLAGS | \ 470 - TCR_SMP_FLAGS | TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ 472 + TCR_SHARED | TCR_TG_FLAGS | TCR_KASLR_FLAGS | TCR_ASID16 | \ 471 473 TCR_TBI0 | TCR_A1 | TCR_KASAN_SW_FLAGS | TCR_MTE_FLAGS 472 474 473 475 tcr_clear_errata_bits tcr, x9, x5
+4 -2
arch/arm64/mm/trans_pgd.c
··· 42 42 * the temporary mappings we use during restore. 43 43 */ 44 44 __set_pte(dst_ptep, pte_mkwrite_novma(pte)); 45 - } else if ((debug_pagealloc_enabled() || 46 - is_kfence_address((void *)addr)) && !pte_none(pte)) { 45 + } else if (!pte_none(pte)) { 47 46 /* 48 47 * debug_pagealloc will removed the PTE_VALID bit if 49 48 * the page isn't in use by the resume kernel. It may have 50 49 * been in use by the original kernel, in which case we need 51 50 * to put it back in our copy to do the restore. 51 + * 52 + * Other cases include kfence / vmalloc / memfd_secret which 53 + * may call `set_direct_map_invalid_noflush()`. 52 54 * 53 55 * Before marking this entry valid, check the pfn should 54 56 * be mapped.
+1
arch/arm64/tools/cpucaps
··· 45 45 HAS_NESTED_VIRT 46 46 HAS_PAN 47 47 HAS_S1PIE 48 + HAS_S1POE 48 49 HAS_RAS_EXTN 49 50 HAS_RNG 50 51 HAS_SB
+30
arch/arm64/tools/sysreg
··· 2029 2029 Field 63:0 ADDR 2030 2030 EndSysreg 2031 2031 2032 + Sysreg PMICNTR_EL0 3 3 9 4 0 2033 + Field 63:0 ICNT 2034 + EndSysreg 2035 + 2036 + Sysreg PMICFILTR_EL0 3 3 9 6 0 2037 + Res0 63:59 2038 + Field 58 SYNC 2039 + Field 57:56 VS 2040 + Res0 55:32 2041 + Field 31 P 2042 + Field 30 U 2043 + Field 29 NSK 2044 + Field 28 NSU 2045 + Field 27 NSH 2046 + Field 26 M 2047 + Res0 25 2048 + Field 24 SH 2049 + Field 23 T 2050 + Field 22 RLK 2051 + Field 21 RLU 2052 + Field 20 RLH 2053 + Res0 19:16 2054 + Field 15:0 evtCount 2055 + EndSysreg 2056 + 2032 2057 Sysreg PMSCR_EL1 3 0 9 9 0 2033 2058 Res0 63:8 2034 2059 Field 7:6 PCT ··· 2176 2151 Field 5 F 2177 2152 Field 4 P 2178 2153 Field 3:0 ALIGN 2154 + EndSysreg 2155 + 2156 + Sysreg PMSELR_EL0 3 3 9 12 5 2157 + Res0 63:5 2158 + Field 4:0 SEL 2179 2159 EndSysreg 2180 2160 2181 2161 SysregFields CONTEXTIDR_ELx
+4
arch/powerpc/Kconfig
··· 1026 1026 1027 1027 If unsure, say y. 1028 1028 1029 + config ARCH_PKEY_BITS 1030 + int 1031 + default 5 1032 + 1029 1033 config PPC_SECURE_BOOT 1030 1034 prompt "Enable secure boot support" 1031 1035 bool
+4
arch/x86/Kconfig
··· 1889 1889 1890 1890 If unsure, say y. 1891 1891 1892 + config ARCH_PKEY_BITS 1893 + int 1894 + default 4 1895 + 1892 1896 choice 1893 1897 prompt "TSX enable mode" 1894 1898 depends on CPU_SUP_INTEL
+8 -1
drivers/acpi/arm64/iort.c
··· 822 822 return NULL; 823 823 824 824 /* Create a copy of SIDs array to associate with this rmr_data */ 825 - sids_copy = kmemdup(sids, num_sids * sizeof(*sids), GFP_KERNEL); 825 + sids_copy = kmemdup_array(sids, num_sids, sizeof(*sids), GFP_KERNEL); 826 826 if (!sids_copy) { 827 827 kfree(rmr_data); 828 828 return NULL; ··· 1702 1702 "Erratum #162001800, Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP08}, 1703 1703 /* HiSilicon Hip09 Platform */ 1704 1704 {"HISI ", "HIP09 ", 0, ACPI_SIG_IORT, greater_than_or_equal, 1705 + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, 1706 + /* HiSilicon Hip10/11 Platform uses the same SMMU IP with Hip09 */ 1707 + {"HISI ", "HIP10 ", 0, ACPI_SIG_IORT, greater_than_or_equal, 1708 + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, 1709 + {"HISI ", "HIP10C ", 0, ACPI_SIG_IORT, greater_than_or_equal, 1710 + "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, 1711 + {"HISI ", "HIP11 ", 0, ACPI_SIG_IORT, greater_than_or_equal, 1705 1712 "Erratum #162001900", IORT_SMMU_V3_PMCG_HISI_HIP09}, 1706 1713 { } 1707 1714 };
+2
drivers/firmware/smccc/kvm_guest.c
··· 39 39 40 40 pr_info("hypervisor services detected (0x%08lx 0x%08lx 0x%08lx 0x%08lx)\n", 41 41 res.a3, res.a2, res.a1, res.a0); 42 + 43 + kvm_arch_init_hyp_services(); 42 44 } 43 45 44 46 bool kvm_arm_hyp_service_available(u32 func_id)
+7
drivers/perf/Kconfig
··· 48 48 Support for PMU events monitoring on the Arm CMN-600 Coherent Mesh 49 49 Network interconnect. 50 50 51 + config ARM_NI 52 + tristate "Arm NI-700 PMU support" 53 + depends on ARM64 || COMPILE_TEST 54 + help 55 + Support for PMU events monitoring on the Arm NI-700 Network-on-Chip 56 + interconnect and family. 57 + 51 58 config ARM_PMU 52 59 depends on ARM || ARM64 53 60 bool "ARM PMU framework"
+1
drivers/perf/Makefile
··· 3 3 obj-$(CONFIG_ARM_CCN) += arm-ccn.o 4 4 obj-$(CONFIG_ARM_CMN) += arm-cmn.o 5 5 obj-$(CONFIG_ARM_DSU_PMU) += arm_dsu_pmu.o 6 + obj-$(CONFIG_ARM_NI) += arm-ni.o 6 7 obj-$(CONFIG_ARM_PMU) += arm_pmu.o arm_pmu_platform.o 7 8 obj-$(CONFIG_ARM_PMU_ACPI) += arm_pmu_acpi.o 8 9 obj-$(CONFIG_ARM_PMUV3) += arm_pmuv3.o
+1 -1
drivers/perf/alibaba_uncore_drw_pmu.c
··· 400 400 } 401 401 402 402 /* clear common counter intr status */ 403 - clr_status = FIELD_PREP(ALI_DRW_PMCOM_CNT_OV_INTR_MASK, 1); 403 + clr_status = FIELD_PREP(ALI_DRW_PMCOM_CNT_OV_INTR_MASK, status); 404 404 writel(clr_status, 405 405 drw_pmu->cfg_base + ALI_DRW_PMU_OV_INTR_CLR); 406 406 }
+107 -75
drivers/perf/apple_m1_cpu_pmu.c
··· 47 47 * implementations, we'll have to introduce per cpu-type tables. 48 48 */ 49 49 enum m1_pmu_events { 50 - M1_PMU_PERFCTR_UNKNOWN_01 = 0x01, 51 - M1_PMU_PERFCTR_CPU_CYCLES = 0x02, 52 - M1_PMU_PERFCTR_INSTRUCTIONS = 0x8c, 53 - M1_PMU_PERFCTR_UNKNOWN_8d = 0x8d, 54 - M1_PMU_PERFCTR_UNKNOWN_8e = 0x8e, 55 - M1_PMU_PERFCTR_UNKNOWN_8f = 0x8f, 56 - M1_PMU_PERFCTR_UNKNOWN_90 = 0x90, 57 - M1_PMU_PERFCTR_UNKNOWN_93 = 0x93, 58 - M1_PMU_PERFCTR_UNKNOWN_94 = 0x94, 59 - M1_PMU_PERFCTR_UNKNOWN_95 = 0x95, 60 - M1_PMU_PERFCTR_UNKNOWN_96 = 0x96, 61 - M1_PMU_PERFCTR_UNKNOWN_97 = 0x97, 62 - M1_PMU_PERFCTR_UNKNOWN_98 = 0x98, 63 - M1_PMU_PERFCTR_UNKNOWN_99 = 0x99, 64 - M1_PMU_PERFCTR_UNKNOWN_9a = 0x9a, 65 - M1_PMU_PERFCTR_UNKNOWN_9b = 0x9b, 66 - M1_PMU_PERFCTR_UNKNOWN_9c = 0x9c, 67 - M1_PMU_PERFCTR_UNKNOWN_9f = 0x9f, 68 - M1_PMU_PERFCTR_UNKNOWN_bf = 0xbf, 69 - M1_PMU_PERFCTR_UNKNOWN_c0 = 0xc0, 70 - M1_PMU_PERFCTR_UNKNOWN_c1 = 0xc1, 71 - M1_PMU_PERFCTR_UNKNOWN_c4 = 0xc4, 72 - M1_PMU_PERFCTR_UNKNOWN_c5 = 0xc5, 73 - M1_PMU_PERFCTR_UNKNOWN_c6 = 0xc6, 74 - M1_PMU_PERFCTR_UNKNOWN_c8 = 0xc8, 75 - M1_PMU_PERFCTR_UNKNOWN_ca = 0xca, 76 - M1_PMU_PERFCTR_UNKNOWN_cb = 0xcb, 77 - M1_PMU_PERFCTR_UNKNOWN_f5 = 0xf5, 78 - M1_PMU_PERFCTR_UNKNOWN_f6 = 0xf6, 79 - M1_PMU_PERFCTR_UNKNOWN_f7 = 0xf7, 80 - M1_PMU_PERFCTR_UNKNOWN_f8 = 0xf8, 81 - M1_PMU_PERFCTR_UNKNOWN_fd = 0xfd, 82 - M1_PMU_PERFCTR_LAST = M1_PMU_CFG_EVENT, 50 + M1_PMU_PERFCTR_RETIRE_UOP = 0x1, 51 + M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE = 0x2, 52 + M1_PMU_PERFCTR_L1I_TLB_FILL = 0x4, 53 + M1_PMU_PERFCTR_L1D_TLB_FILL = 0x5, 54 + M1_PMU_PERFCTR_MMU_TABLE_WALK_INSTRUCTION = 0x7, 55 + M1_PMU_PERFCTR_MMU_TABLE_WALK_DATA = 0x8, 56 + M1_PMU_PERFCTR_L2_TLB_MISS_INSTRUCTION = 0xa, 57 + M1_PMU_PERFCTR_L2_TLB_MISS_DATA = 0xb, 58 + M1_PMU_PERFCTR_MMU_VIRTUAL_MEMORY_FAULT_NONSPEC = 0xd, 59 + M1_PMU_PERFCTR_SCHEDULE_UOP = 0x52, 60 + M1_PMU_PERFCTR_INTERRUPT_PENDING = 0x6c, 61 + M1_PMU_PERFCTR_MAP_STALL_DISPATCH = 0x70, 62 + M1_PMU_PERFCTR_MAP_REWIND = 0x75, 63 + M1_PMU_PERFCTR_MAP_STALL = 0x76, 64 + M1_PMU_PERFCTR_MAP_INT_UOP = 0x7c, 65 + M1_PMU_PERFCTR_MAP_LDST_UOP = 0x7d, 66 + M1_PMU_PERFCTR_MAP_SIMD_UOP = 0x7e, 67 + M1_PMU_PERFCTR_FLUSH_RESTART_OTHER_NONSPEC = 0x84, 68 + M1_PMU_PERFCTR_INST_ALL = 0x8c, 69 + M1_PMU_PERFCTR_INST_BRANCH = 0x8d, 70 + M1_PMU_PERFCTR_INST_BRANCH_CALL = 0x8e, 71 + M1_PMU_PERFCTR_INST_BRANCH_RET = 0x8f, 72 + M1_PMU_PERFCTR_INST_BRANCH_TAKEN = 0x90, 73 + M1_PMU_PERFCTR_INST_BRANCH_INDIR = 0x93, 74 + M1_PMU_PERFCTR_INST_BRANCH_COND = 0x94, 75 + M1_PMU_PERFCTR_INST_INT_LD = 0x95, 76 + M1_PMU_PERFCTR_INST_INT_ST = 0x96, 77 + M1_PMU_PERFCTR_INST_INT_ALU = 0x97, 78 + M1_PMU_PERFCTR_INST_SIMD_LD = 0x98, 79 + M1_PMU_PERFCTR_INST_SIMD_ST = 0x99, 80 + M1_PMU_PERFCTR_INST_SIMD_ALU = 0x9a, 81 + M1_PMU_PERFCTR_INST_LDST = 0x9b, 82 + M1_PMU_PERFCTR_INST_BARRIER = 0x9c, 83 + M1_PMU_PERFCTR_UNKNOWN_9f = 0x9f, 84 + M1_PMU_PERFCTR_L1D_TLB_ACCESS = 0xa0, 85 + M1_PMU_PERFCTR_L1D_TLB_MISS = 0xa1, 86 + M1_PMU_PERFCTR_L1D_CACHE_MISS_ST = 0xa2, 87 + M1_PMU_PERFCTR_L1D_CACHE_MISS_LD = 0xa3, 88 + M1_PMU_PERFCTR_LD_UNIT_UOP = 0xa6, 89 + M1_PMU_PERFCTR_ST_UNIT_UOP = 0xa7, 90 + M1_PMU_PERFCTR_L1D_CACHE_WRITEBACK = 0xa8, 91 + M1_PMU_PERFCTR_LDST_X64_UOP = 0xb1, 92 + M1_PMU_PERFCTR_LDST_XPG_UOP = 0xb2, 93 + M1_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_SUCC = 0xb3, 94 + M1_PMU_PERFCTR_ATOMIC_OR_EXCLUSIVE_FAIL = 0xb4, 95 + M1_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC = 0xbf, 96 + M1_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC = 0xc0, 97 + M1_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC = 0xc1, 98 + M1_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC = 0xc4, 99 + M1_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC = 0xc5, 100 + M1_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC = 0xc6, 101 + M1_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC = 0xc8, 102 + M1_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC = 0xca, 103 + M1_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC = 0xcb, 104 + M1_PMU_PERFCTR_L1I_TLB_MISS_DEMAND = 0xd4, 105 + M1_PMU_PERFCTR_MAP_DISPATCH_BUBBLE = 0xd6, 106 + M1_PMU_PERFCTR_L1I_CACHE_MISS_DEMAND = 0xdb, 107 + M1_PMU_PERFCTR_FETCH_RESTART = 0xde, 108 + M1_PMU_PERFCTR_ST_NT_UOP = 0xe5, 109 + M1_PMU_PERFCTR_LD_NT_UOP = 0xe6, 110 + M1_PMU_PERFCTR_UNKNOWN_f5 = 0xf5, 111 + M1_PMU_PERFCTR_UNKNOWN_f6 = 0xf6, 112 + M1_PMU_PERFCTR_UNKNOWN_f7 = 0xf7, 113 + M1_PMU_PERFCTR_UNKNOWN_f8 = 0xf8, 114 + M1_PMU_PERFCTR_UNKNOWN_fd = 0xfd, 115 + M1_PMU_PERFCTR_LAST = M1_PMU_CFG_EVENT, 83 116 84 117 /* 85 118 * From this point onwards, these are not actual HW events, 86 119 * but attributes that get stored in hw->config_base. 87 120 */ 88 - M1_PMU_CFG_COUNT_USER = BIT(8), 89 - M1_PMU_CFG_COUNT_KERNEL = BIT(9), 121 + M1_PMU_CFG_COUNT_USER = BIT(8), 122 + M1_PMU_CFG_COUNT_KERNEL = BIT(9), 90 123 }; 91 124 92 125 /* ··· 129 96 * counters had strange affinities. 130 97 */ 131 98 static const u16 m1_pmu_event_affinity[M1_PMU_PERFCTR_LAST + 1] = { 132 - [0 ... M1_PMU_PERFCTR_LAST] = ANY_BUT_0_1, 133 - [M1_PMU_PERFCTR_UNKNOWN_01] = BIT(7), 134 - [M1_PMU_PERFCTR_CPU_CYCLES] = ANY_BUT_0_1 | BIT(0), 135 - [M1_PMU_PERFCTR_INSTRUCTIONS] = BIT(7) | BIT(1), 136 - [M1_PMU_PERFCTR_UNKNOWN_8d] = ONLY_5_6_7, 137 - [M1_PMU_PERFCTR_UNKNOWN_8e] = ONLY_5_6_7, 138 - [M1_PMU_PERFCTR_UNKNOWN_8f] = ONLY_5_6_7, 139 - [M1_PMU_PERFCTR_UNKNOWN_90] = ONLY_5_6_7, 140 - [M1_PMU_PERFCTR_UNKNOWN_93] = ONLY_5_6_7, 141 - [M1_PMU_PERFCTR_UNKNOWN_94] = ONLY_5_6_7, 142 - [M1_PMU_PERFCTR_UNKNOWN_95] = ONLY_5_6_7, 143 - [M1_PMU_PERFCTR_UNKNOWN_96] = ONLY_5_6_7, 144 - [M1_PMU_PERFCTR_UNKNOWN_97] = BIT(7), 145 - [M1_PMU_PERFCTR_UNKNOWN_98] = ONLY_5_6_7, 146 - [M1_PMU_PERFCTR_UNKNOWN_99] = ONLY_5_6_7, 147 - [M1_PMU_PERFCTR_UNKNOWN_9a] = BIT(7), 148 - [M1_PMU_PERFCTR_UNKNOWN_9b] = ONLY_5_6_7, 149 - [M1_PMU_PERFCTR_UNKNOWN_9c] = ONLY_5_6_7, 150 - [M1_PMU_PERFCTR_UNKNOWN_9f] = BIT(7), 151 - [M1_PMU_PERFCTR_UNKNOWN_bf] = ONLY_5_6_7, 152 - [M1_PMU_PERFCTR_UNKNOWN_c0] = ONLY_5_6_7, 153 - [M1_PMU_PERFCTR_UNKNOWN_c1] = ONLY_5_6_7, 154 - [M1_PMU_PERFCTR_UNKNOWN_c4] = ONLY_5_6_7, 155 - [M1_PMU_PERFCTR_UNKNOWN_c5] = ONLY_5_6_7, 156 - [M1_PMU_PERFCTR_UNKNOWN_c6] = ONLY_5_6_7, 157 - [M1_PMU_PERFCTR_UNKNOWN_c8] = ONLY_5_6_7, 158 - [M1_PMU_PERFCTR_UNKNOWN_ca] = ONLY_5_6_7, 159 - [M1_PMU_PERFCTR_UNKNOWN_cb] = ONLY_5_6_7, 160 - [M1_PMU_PERFCTR_UNKNOWN_f5] = ONLY_2_4_6, 161 - [M1_PMU_PERFCTR_UNKNOWN_f6] = ONLY_2_4_6, 162 - [M1_PMU_PERFCTR_UNKNOWN_f7] = ONLY_2_4_6, 163 - [M1_PMU_PERFCTR_UNKNOWN_f8] = ONLY_2_TO_7, 164 - [M1_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6, 99 + [0 ... M1_PMU_PERFCTR_LAST] = ANY_BUT_0_1, 100 + [M1_PMU_PERFCTR_RETIRE_UOP] = BIT(7), 101 + [M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE] = ANY_BUT_0_1 | BIT(0), 102 + [M1_PMU_PERFCTR_INST_ALL] = BIT(7) | BIT(1), 103 + [M1_PMU_PERFCTR_INST_BRANCH] = ONLY_5_6_7, 104 + [M1_PMU_PERFCTR_INST_BRANCH_CALL] = ONLY_5_6_7, 105 + [M1_PMU_PERFCTR_INST_BRANCH_RET] = ONLY_5_6_7, 106 + [M1_PMU_PERFCTR_INST_BRANCH_TAKEN] = ONLY_5_6_7, 107 + [M1_PMU_PERFCTR_INST_BRANCH_INDIR] = ONLY_5_6_7, 108 + [M1_PMU_PERFCTR_INST_BRANCH_COND] = ONLY_5_6_7, 109 + [M1_PMU_PERFCTR_INST_INT_LD] = ONLY_5_6_7, 110 + [M1_PMU_PERFCTR_INST_INT_ST] = BIT(7), 111 + [M1_PMU_PERFCTR_INST_INT_ALU] = BIT(7), 112 + [M1_PMU_PERFCTR_INST_SIMD_LD] = ONLY_5_6_7, 113 + [M1_PMU_PERFCTR_INST_SIMD_ST] = ONLY_5_6_7, 114 + [M1_PMU_PERFCTR_INST_SIMD_ALU] = BIT(7), 115 + [M1_PMU_PERFCTR_INST_LDST] = BIT(7), 116 + [M1_PMU_PERFCTR_INST_BARRIER] = ONLY_5_6_7, 117 + [M1_PMU_PERFCTR_UNKNOWN_9f] = BIT(7), 118 + [M1_PMU_PERFCTR_L1D_CACHE_MISS_LD_NONSPEC] = ONLY_5_6_7, 119 + [M1_PMU_PERFCTR_L1D_CACHE_MISS_ST_NONSPEC] = ONLY_5_6_7, 120 + [M1_PMU_PERFCTR_L1D_TLB_MISS_NONSPEC] = ONLY_5_6_7, 121 + [M1_PMU_PERFCTR_ST_MEMORY_ORDER_VIOLATION_NONSPEC] = ONLY_5_6_7, 122 + [M1_PMU_PERFCTR_BRANCH_COND_MISPRED_NONSPEC] = ONLY_5_6_7, 123 + [M1_PMU_PERFCTR_BRANCH_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, 124 + [M1_PMU_PERFCTR_BRANCH_RET_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, 125 + [M1_PMU_PERFCTR_BRANCH_CALL_INDIR_MISPRED_NONSPEC] = ONLY_5_6_7, 126 + [M1_PMU_PERFCTR_BRANCH_MISPRED_NONSPEC] = ONLY_5_6_7, 127 + [M1_PMU_PERFCTR_UNKNOWN_f5] = ONLY_2_4_6, 128 + [M1_PMU_PERFCTR_UNKNOWN_f6] = ONLY_2_4_6, 129 + [M1_PMU_PERFCTR_UNKNOWN_f7] = ONLY_2_4_6, 130 + [M1_PMU_PERFCTR_UNKNOWN_f8] = ONLY_2_TO_7, 131 + [M1_PMU_PERFCTR_UNKNOWN_fd] = ONLY_2_4_6, 165 132 }; 166 133 167 134 static const unsigned m1_pmu_perf_map[PERF_COUNT_HW_MAX] = { 168 135 PERF_MAP_ALL_UNSUPPORTED, 169 - [PERF_COUNT_HW_CPU_CYCLES] = M1_PMU_PERFCTR_CPU_CYCLES, 170 - [PERF_COUNT_HW_INSTRUCTIONS] = M1_PMU_PERFCTR_INSTRUCTIONS, 171 - /* No idea about the rest yet */ 136 + [PERF_COUNT_HW_CPU_CYCLES] = M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE, 137 + [PERF_COUNT_HW_INSTRUCTIONS] = M1_PMU_PERFCTR_INST_ALL, 172 138 }; 173 139 174 140 /* sysfs definitions */ ··· 186 154 PMU_EVENT_ATTR_ID(name, m1_pmu_events_sysfs_show, config) 187 155 188 156 static struct attribute *m1_pmu_event_attrs[] = { 189 - M1_PMU_EVENT_ATTR(cycles, M1_PMU_PERFCTR_CPU_CYCLES), 190 - M1_PMU_EVENT_ATTR(instructions, M1_PMU_PERFCTR_INSTRUCTIONS), 157 + M1_PMU_EVENT_ATTR(cycles, M1_PMU_PERFCTR_CORE_ACTIVE_CYCLE), 158 + M1_PMU_EVENT_ATTR(instructions, M1_PMU_PERFCTR_INST_ALL), 191 159 NULL, 192 160 }; 193 161 ··· 432 400 433 401 regs = get_irq_regs(); 434 402 435 - for (idx = 0; idx < cpu_pmu->num_events; idx++) { 403 + for_each_set_bit(idx, cpu_pmu->cntr_mask, M1_PMU_NR_COUNTERS) { 436 404 struct perf_event *event = cpuc->events[idx]; 437 405 struct perf_sample_data data; 438 406 ··· 592 560 cpu_pmu->reset = m1_pmu_reset; 593 561 cpu_pmu->set_event_filter = m1_pmu_set_event_filter; 594 562 595 - cpu_pmu->num_events = M1_PMU_NR_COUNTERS; 563 + bitmap_set(cpu_pmu->cntr_mask, 0, M1_PMU_NR_COUNTERS); 596 564 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_EVENTS] = &m1_pmu_events_attr_group; 597 565 cpu_pmu->attr_groups[ARMPMU_ATTR_GROUP_FORMATS] = &m1_pmu_format_attr_group; 598 566 return 0;
+177 -141
drivers/perf/arm-cmn.c
··· 24 24 #define CMN_NI_NODE_ID GENMASK_ULL(31, 16) 25 25 #define CMN_NI_LOGICAL_ID GENMASK_ULL(47, 32) 26 26 27 - #define CMN_NODEID_DEVID(reg) ((reg) & 3) 28 - #define CMN_NODEID_EXT_DEVID(reg) ((reg) & 1) 29 - #define CMN_NODEID_PID(reg) (((reg) >> 2) & 1) 30 - #define CMN_NODEID_EXT_PID(reg) (((reg) >> 1) & 3) 31 - #define CMN_NODEID_1x1_PID(reg) (((reg) >> 2) & 7) 32 - #define CMN_NODEID_X(reg, bits) ((reg) >> (3 + (bits))) 33 - #define CMN_NODEID_Y(reg, bits) (((reg) >> 3) & ((1U << (bits)) - 1)) 34 - 35 27 #define CMN_CHILD_INFO 0x0080 36 28 #define CMN_CI_CHILD_COUNT GENMASK_ULL(15, 0) 37 29 #define CMN_CI_CHILD_PTR_OFFSET GENMASK_ULL(31, 16) ··· 35 43 #define CMN_MAX_XPS (CMN_MAX_DIMENSION * CMN_MAX_DIMENSION) 36 44 #define CMN_MAX_DTMS (CMN_MAX_XPS + (CMN_MAX_DIMENSION - 1) * 4) 37 45 46 + /* Currently XPs are the node type we can have most of; others top out at 128 */ 47 + #define CMN_MAX_NODES_PER_EVENT CMN_MAX_XPS 48 + 38 49 /* The CFG node has various info besides the discovery tree */ 39 50 #define CMN_CFGM_PERIPH_ID_01 0x0008 40 51 #define CMN_CFGM_PID0_PART_0 GENMASK_ULL(7, 0) ··· 45 50 #define CMN_CFGM_PERIPH_ID_23 0x0010 46 51 #define CMN_CFGM_PID2_REVISION GENMASK_ULL(7, 4) 47 52 48 - #define CMN_CFGM_INFO_GLOBAL 0x900 53 + #define CMN_CFGM_INFO_GLOBAL 0x0900 49 54 #define CMN_INFO_MULTIPLE_DTM_EN BIT_ULL(63) 50 55 #define CMN_INFO_RSP_VC_NUM GENMASK_ULL(53, 52) 51 56 #define CMN_INFO_DAT_VC_NUM GENMASK_ULL(51, 50) 57 + #define CMN_INFO_DEVICE_ISO_ENABLE BIT_ULL(44) 52 58 53 - #define CMN_CFGM_INFO_GLOBAL_1 0x908 59 + #define CMN_CFGM_INFO_GLOBAL_1 0x0908 54 60 #define CMN_INFO_SNP_VC_NUM GENMASK_ULL(3, 2) 55 61 #define CMN_INFO_REQ_VC_NUM GENMASK_ULL(1, 0) 56 62 57 63 /* XPs also have some local topology info which has uses too */ 58 64 #define CMN_MXP__CONNECT_INFO(p) (0x0008 + 8 * (p)) 59 - #define CMN__CONNECT_INFO_DEVICE_TYPE GENMASK_ULL(4, 0) 65 + #define CMN__CONNECT_INFO_DEVICE_TYPE GENMASK_ULL(5, 0) 60 66 61 67 #define CMN_MAX_PORTS 6 62 68 #define CI700_CONNECT_INFO_P2_5_OFFSET 0x10 63 69 64 70 /* PMU registers occupy the 3rd 4KB page of each node's region */ 65 71 #define CMN_PMU_OFFSET 0x2000 72 + /* ...except when they don't :( */ 73 + #define CMN_S3_DTM_OFFSET 0xa000 74 + #define CMN_S3_PMU_OFFSET 0xd900 66 75 67 76 /* For most nodes, this is all there is */ 68 77 #define CMN_PMU_EVENT_SEL 0x000 ··· 77 78 /* Technically this is 4 bits wide on DNs, but we only use 2 there anyway */ 78 79 #define CMN__PMU_OCCUP1_ID GENMASK_ULL(34, 32) 79 80 80 - /* HN-Ps are weird... */ 81 + /* Some types are designed to coexist with another device in the same node */ 82 + #define CMN_CCLA_PMU_EVENT_SEL 0x008 81 83 #define CMN_HNP_PMU_EVENT_SEL 0x008 82 84 83 85 /* DTMs live in the PMU space of XP registers */ ··· 123 123 /* The DTC node is where the magic happens */ 124 124 #define CMN_DT_DTC_CTL 0x0a00 125 125 #define CMN_DT_DTC_CTL_DT_EN BIT(0) 126 + #define CMN_DT_DTC_CTL_CG_DISABLE BIT(10) 126 127 127 128 /* DTC counters are paired in 64-bit registers on a 16-byte stride. Yuck */ 128 129 #define _CMN_DT_CNT_REG(n) ((((n) / 2) * 4 + (n) % 2) * 4) 129 - #define CMN_DT_PMEVCNT(n) (CMN_PMU_OFFSET + _CMN_DT_CNT_REG(n)) 130 - #define CMN_DT_PMCCNTR (CMN_PMU_OFFSET + 0x40) 130 + #define CMN_DT_PMEVCNT(dtc, n) ((dtc)->pmu_base + _CMN_DT_CNT_REG(n)) 131 + #define CMN_DT_PMCCNTR(dtc) ((dtc)->pmu_base + 0x40) 131 132 132 - #define CMN_DT_PMEVCNTSR(n) (CMN_PMU_OFFSET + 0x50 + _CMN_DT_CNT_REG(n)) 133 - #define CMN_DT_PMCCNTRSR (CMN_PMU_OFFSET + 0x90) 133 + #define CMN_DT_PMEVCNTSR(dtc, n) ((dtc)->pmu_base + 0x50 + _CMN_DT_CNT_REG(n)) 134 + #define CMN_DT_PMCCNTRSR(dtc) ((dtc)->pmu_base + 0x90) 134 135 135 - #define CMN_DT_PMCR (CMN_PMU_OFFSET + 0x100) 136 + #define CMN_DT_PMCR(dtc) ((dtc)->pmu_base + 0x100) 136 137 #define CMN_DT_PMCR_PMU_EN BIT(0) 137 138 #define CMN_DT_PMCR_CNTR_RST BIT(5) 138 139 #define CMN_DT_PMCR_OVFL_INTR_EN BIT(6) 139 140 140 - #define CMN_DT_PMOVSR (CMN_PMU_OFFSET + 0x118) 141 - #define CMN_DT_PMOVSR_CLR (CMN_PMU_OFFSET + 0x120) 141 + #define CMN_DT_PMOVSR(dtc) ((dtc)->pmu_base + 0x118) 142 + #define CMN_DT_PMOVSR_CLR(dtc) ((dtc)->pmu_base + 0x120) 142 143 143 - #define CMN_DT_PMSSR (CMN_PMU_OFFSET + 0x128) 144 + #define CMN_DT_PMSSR(dtc) ((dtc)->pmu_base + 0x128) 144 145 #define CMN_DT_PMSSR_SS_STATUS(n) BIT(n) 145 146 146 - #define CMN_DT_PMSRR (CMN_PMU_OFFSET + 0x130) 147 + #define CMN_DT_PMSRR(dtc) ((dtc)->pmu_base + 0x130) 147 148 #define CMN_DT_PMSRR_SS_REQ BIT(0) 148 149 149 150 #define CMN_DT_NUM_COUNTERS 8 ··· 199 198 CMN650 = 2, 200 199 CMN700 = 4, 201 200 CI700 = 8, 201 + CMNS3 = 16, 202 202 /* ...and then we can use bitmap tricks for commonality */ 203 203 CMN_ANY = -1, 204 204 NOT_CMN600 = -2, 205 - CMN_650ON = CMN650 | CMN700, 205 + CMN_650ON = CMN650 | CMN700 | CMNS3, 206 206 }; 207 207 208 208 /* Actual part numbers and revision IDs defined by the hardware */ ··· 212 210 PART_CMN650 = 0x436, 213 211 PART_CMN700 = 0x43c, 214 212 PART_CI700 = 0x43a, 213 + PART_CMN_S3 = 0x43e, 215 214 }; 216 215 217 216 /* CMN-600 r0px shouldn't exist in silicon, thankfully */ ··· 264 261 CMN_TYPE_HNS = 0x200, 265 262 CMN_TYPE_HNS_MPAM_S, 266 263 CMN_TYPE_HNS_MPAM_NS, 264 + CMN_TYPE_APB = 0x1000, 267 265 /* Not a real node type */ 268 266 CMN_TYPE_WP = 0x7770 269 267 }; ··· 284 280 u16 id, logid; 285 281 enum cmn_node_type type; 286 282 283 + /* XP properties really, but replicated to children for convenience */ 287 284 u8 dtm; 288 285 s8 dtc; 286 + u8 portid_bits:4; 287 + u8 deviceid_bits:4; 289 288 /* DN/HN-F/CXHA */ 290 289 struct { 291 290 u8 val : 4; ··· 314 307 315 308 struct arm_cmn_dtc { 316 309 void __iomem *base; 310 + void __iomem *pmu_base; 317 311 int irq; 318 - int irq_friend; 312 + s8 irq_friend; 319 313 bool cc_active; 320 314 321 315 struct perf_event *counters[CMN_DT_NUM_COUNTERS]; ··· 365 357 static int arm_cmn_hp_state; 366 358 367 359 struct arm_cmn_nodeid { 368 - u8 x; 369 - u8 y; 370 360 u8 port; 371 361 u8 dev; 372 362 }; 373 363 374 364 static int arm_cmn_xyidbits(const struct arm_cmn *cmn) 375 365 { 376 - return fls((cmn->mesh_x - 1) | (cmn->mesh_y - 1) | 2); 366 + return fls((cmn->mesh_x - 1) | (cmn->mesh_y - 1)); 377 367 } 378 368 379 - static struct arm_cmn_nodeid arm_cmn_nid(const struct arm_cmn *cmn, u16 id) 369 + static struct arm_cmn_nodeid arm_cmn_nid(const struct arm_cmn_node *dn) 380 370 { 381 371 struct arm_cmn_nodeid nid; 382 372 383 - if (cmn->num_xps == 1) { 384 - nid.x = 0; 385 - nid.y = 0; 386 - nid.port = CMN_NODEID_1x1_PID(id); 387 - nid.dev = CMN_NODEID_DEVID(id); 388 - } else { 389 - int bits = arm_cmn_xyidbits(cmn); 390 - 391 - nid.x = CMN_NODEID_X(id, bits); 392 - nid.y = CMN_NODEID_Y(id, bits); 393 - if (cmn->ports_used & 0xc) { 394 - nid.port = CMN_NODEID_EXT_PID(id); 395 - nid.dev = CMN_NODEID_EXT_DEVID(id); 396 - } else { 397 - nid.port = CMN_NODEID_PID(id); 398 - nid.dev = CMN_NODEID_DEVID(id); 399 - } 400 - } 373 + nid.dev = dn->id & ((1U << dn->deviceid_bits) - 1); 374 + nid.port = (dn->id >> dn->deviceid_bits) & ((1U << dn->portid_bits) - 1); 401 375 return nid; 402 376 } 403 377 404 378 static struct arm_cmn_node *arm_cmn_node_to_xp(const struct arm_cmn *cmn, 405 379 const struct arm_cmn_node *dn) 406 380 { 407 - struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, dn->id); 408 - int xp_idx = cmn->mesh_x * nid.y + nid.x; 381 + int id = dn->id >> (dn->portid_bits + dn->deviceid_bits); 382 + int bits = arm_cmn_xyidbits(cmn); 383 + int x = id >> bits; 384 + int y = id & ((1U << bits) - 1); 409 385 410 - return cmn->xps + xp_idx; 386 + return cmn->xps + cmn->mesh_x * y + x; 411 387 } 412 388 static struct arm_cmn_node *arm_cmn_node(const struct arm_cmn *cmn, 413 389 enum cmn_node_type type) ··· 415 423 return CMN700; 416 424 case PART_CI700: 417 425 return CI700; 426 + case PART_CMN_S3: 427 + return CMNS3; 418 428 default: 419 429 return 0; 420 430 }; 421 431 } 422 432 433 + static int arm_cmn_pmu_offset(const struct arm_cmn *cmn, const struct arm_cmn_node *dn) 434 + { 435 + if (cmn->part == PART_CMN_S3) { 436 + if (dn->type == CMN_TYPE_XP) 437 + return CMN_S3_DTM_OFFSET; 438 + return CMN_S3_PMU_OFFSET; 439 + } 440 + return CMN_PMU_OFFSET; 441 + } 442 + 423 443 static u32 arm_cmn_device_connect_info(const struct arm_cmn *cmn, 424 444 const struct arm_cmn_node *xp, int port) 425 445 { 426 - int offset = CMN_MXP__CONNECT_INFO(port); 446 + int offset = CMN_MXP__CONNECT_INFO(port) - arm_cmn_pmu_offset(cmn, xp); 427 447 428 448 if (port >= 2) { 429 449 if (cmn->part == PART_CMN600 || cmn->part == PART_CMN650) ··· 448 444 offset += CI700_CONNECT_INFO_P2_5_OFFSET; 449 445 } 450 446 451 - return readl_relaxed(xp->pmu_base - CMN_PMU_OFFSET + offset); 447 + return readl_relaxed(xp->pmu_base + offset); 452 448 } 453 449 454 450 static struct dentry *arm_cmn_debugfs; ··· 482 478 case 0x17: return "RN-F_C_E|"; 483 479 case 0x18: return " RN-F_E |"; 484 480 case 0x19: return "RN-F_E_E|"; 481 + case 0x1a: return " HN-S |"; 482 + case 0x1b: return " LCN |"; 485 483 case 0x1c: return " MTSX |"; 486 484 case 0x1d: return " HN-V |"; 487 485 case 0x1e: return " CCG |"; 486 + case 0x20: return " RN-F_F |"; 487 + case 0x21: return "RN-F_F_E|"; 488 + case 0x22: return " SN-F_F |"; 488 489 default: return " ???? |"; 489 490 } 490 491 } 491 492 492 - static void arm_cmn_show_logid(struct seq_file *s, int x, int y, int p, int d) 493 + static void arm_cmn_show_logid(struct seq_file *s, const struct arm_cmn_node *xp, int p, int d) 493 494 { 494 495 struct arm_cmn *cmn = s->private; 495 496 struct arm_cmn_node *dn; 497 + u16 id = xp->id | d | (p << xp->deviceid_bits); 496 498 497 499 for (dn = cmn->dns; dn->type; dn++) { 498 - struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, dn->id); 499 500 int pad = dn->logid < 10; 500 501 501 502 if (dn->type == CMN_TYPE_XP) ··· 509 500 if (dn->type < CMN_TYPE_HNI) 510 501 continue; 511 502 512 - if (nid.x != x || nid.y != y || nid.port != p || nid.dev != d) 503 + if (dn->id != id) 513 504 continue; 514 505 515 506 seq_printf(s, " %*c#%-*d |", pad + 1, ' ', 3 - pad, dn->logid); ··· 530 521 y = cmn->mesh_y; 531 522 while (y--) { 532 523 int xp_base = cmn->mesh_x * y; 524 + struct arm_cmn_node *xp = cmn->xps + xp_base; 533 525 u8 port[CMN_MAX_PORTS][CMN_MAX_DIMENSION]; 534 526 535 527 for (x = 0; x < cmn->mesh_x; x++) ··· 538 528 539 529 seq_printf(s, "\n%-2d |", y); 540 530 for (x = 0; x < cmn->mesh_x; x++) { 541 - struct arm_cmn_node *xp = cmn->xps + xp_base + x; 542 - 543 531 for (p = 0; p < CMN_MAX_PORTS; p++) 544 - port[p][x] = arm_cmn_device_connect_info(cmn, xp, p); 532 + port[p][x] = arm_cmn_device_connect_info(cmn, xp + x, p); 545 533 seq_printf(s, " XP #%-3d|", xp_base + x); 546 534 } 547 535 548 536 seq_puts(s, "\n |"); 549 537 for (x = 0; x < cmn->mesh_x; x++) { 550 - s8 dtc = cmn->xps[xp_base + x].dtc; 538 + s8 dtc = xp[x].dtc; 551 539 552 540 if (dtc < 0) 553 541 seq_puts(s, " DTC ?? |"); ··· 562 554 seq_puts(s, arm_cmn_device_type(port[p][x])); 563 555 seq_puts(s, "\n 0|"); 564 556 for (x = 0; x < cmn->mesh_x; x++) 565 - arm_cmn_show_logid(s, x, y, p, 0); 557 + arm_cmn_show_logid(s, xp + x, p, 0); 566 558 seq_puts(s, "\n 1|"); 567 559 for (x = 0; x < cmn->mesh_x; x++) 568 - arm_cmn_show_logid(s, x, y, p, 1); 560 + arm_cmn_show_logid(s, xp + x, p, 1); 569 561 } 570 562 seq_puts(s, "\n-----+"); 571 563 } ··· 593 585 594 586 struct arm_cmn_hw_event { 595 587 struct arm_cmn_node *dn; 596 - u64 dtm_idx[4]; 588 + u64 dtm_idx[DIV_ROUND_UP(CMN_MAX_NODES_PER_EVENT * 2, 64)]; 597 589 s8 dtc_idx[CMN_MAX_DTCS]; 598 590 u8 num_dns; 599 591 u8 dtm_offset; ··· 607 599 bool wide_sel; 608 600 enum cmn_filter_select filter_sel; 609 601 }; 602 + static_assert(sizeof(struct arm_cmn_hw_event) <= offsetof(struct hw_perf_event, target)); 610 603 611 604 #define for_each_hw_dn(hw, dn, i) \ 612 605 for (i = 0, dn = hw->dn; i < hw->num_dns; i++, dn++) ··· 618 609 619 610 static struct arm_cmn_hw_event *to_cmn_hw(struct perf_event *event) 620 611 { 621 - BUILD_BUG_ON(sizeof(struct arm_cmn_hw_event) > offsetof(struct hw_perf_event, target)); 622 612 return (struct arm_cmn_hw_event *)&event->hw; 623 613 } 624 614 ··· 798 790 CMN_EVENT_ATTR(CMN_ANY, cxha_##_name, CMN_TYPE_CXHA, _event) 799 791 #define CMN_EVENT_CCRA(_name, _event) \ 800 792 CMN_EVENT_ATTR(CMN_ANY, ccra_##_name, CMN_TYPE_CCRA, _event) 801 - #define CMN_EVENT_CCHA(_name, _event) \ 802 - CMN_EVENT_ATTR(CMN_ANY, ccha_##_name, CMN_TYPE_CCHA, _event) 793 + #define CMN_EVENT_CCHA(_model, _name, _event) \ 794 + CMN_EVENT_ATTR(_model, ccha_##_name, CMN_TYPE_CCHA, _event) 803 795 #define CMN_EVENT_CCLA(_name, _event) \ 804 796 CMN_EVENT_ATTR(CMN_ANY, ccla_##_name, CMN_TYPE_CCLA, _event) 805 797 #define CMN_EVENT_CCLA_RNI(_name, _event) \ ··· 1157 1149 CMN_EVENT_CCRA(wdb_alloc, 0x59), 1158 1150 CMN_EVENT_CCRA(ssb_alloc, 0x5a), 1159 1151 1160 - CMN_EVENT_CCHA(rddatbyp, 0x61), 1161 - CMN_EVENT_CCHA(chirsp_up_stall, 0x62), 1162 - CMN_EVENT_CCHA(chidat_up_stall, 0x63), 1163 - CMN_EVENT_CCHA(snppcrd_link0_stall, 0x64), 1164 - CMN_EVENT_CCHA(snppcrd_link1_stall, 0x65), 1165 - CMN_EVENT_CCHA(snppcrd_link2_stall, 0x66), 1166 - CMN_EVENT_CCHA(reqtrk_occ, 0x67), 1167 - CMN_EVENT_CCHA(rdb_occ, 0x68), 1168 - CMN_EVENT_CCHA(rdbyp_occ, 0x69), 1169 - CMN_EVENT_CCHA(wdb_occ, 0x6a), 1170 - CMN_EVENT_CCHA(snptrk_occ, 0x6b), 1171 - CMN_EVENT_CCHA(sdb_occ, 0x6c), 1172 - CMN_EVENT_CCHA(snphaz_occ, 0x6d), 1173 - CMN_EVENT_CCHA(reqtrk_alloc, 0x6e), 1174 - CMN_EVENT_CCHA(rdb_alloc, 0x6f), 1175 - CMN_EVENT_CCHA(rdbyp_alloc, 0x70), 1176 - CMN_EVENT_CCHA(wdb_alloc, 0x71), 1177 - CMN_EVENT_CCHA(snptrk_alloc, 0x72), 1178 - CMN_EVENT_CCHA(sdb_alloc, 0x73), 1179 - CMN_EVENT_CCHA(snphaz_alloc, 0x74), 1180 - CMN_EVENT_CCHA(pb_rhu_req_occ, 0x75), 1181 - CMN_EVENT_CCHA(pb_rhu_req_alloc, 0x76), 1182 - CMN_EVENT_CCHA(pb_rhu_pcie_req_occ, 0x77), 1183 - CMN_EVENT_CCHA(pb_rhu_pcie_req_alloc, 0x78), 1184 - CMN_EVENT_CCHA(pb_pcie_wr_req_occ, 0x79), 1185 - CMN_EVENT_CCHA(pb_pcie_wr_req_alloc, 0x7a), 1186 - CMN_EVENT_CCHA(pb_pcie_reg_req_occ, 0x7b), 1187 - CMN_EVENT_CCHA(pb_pcie_reg_req_alloc, 0x7c), 1188 - CMN_EVENT_CCHA(pb_pcie_rsvd_req_occ, 0x7d), 1189 - CMN_EVENT_CCHA(pb_pcie_rsvd_req_alloc, 0x7e), 1190 - CMN_EVENT_CCHA(pb_rhu_dat_occ, 0x7f), 1191 - CMN_EVENT_CCHA(pb_rhu_dat_alloc, 0x80), 1192 - CMN_EVENT_CCHA(pb_rhu_pcie_dat_occ, 0x81), 1193 - CMN_EVENT_CCHA(pb_rhu_pcie_dat_alloc, 0x82), 1194 - CMN_EVENT_CCHA(pb_pcie_wr_dat_occ, 0x83), 1195 - CMN_EVENT_CCHA(pb_pcie_wr_dat_alloc, 0x84), 1152 + CMN_EVENT_CCHA(CMN_ANY, rddatbyp, 0x61), 1153 + CMN_EVENT_CCHA(CMN_ANY, chirsp_up_stall, 0x62), 1154 + CMN_EVENT_CCHA(CMN_ANY, chidat_up_stall, 0x63), 1155 + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link0_stall, 0x64), 1156 + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link1_stall, 0x65), 1157 + CMN_EVENT_CCHA(CMN_ANY, snppcrd_link2_stall, 0x66), 1158 + CMN_EVENT_CCHA(CMN_ANY, reqtrk_occ, 0x67), 1159 + CMN_EVENT_CCHA(CMN_ANY, rdb_occ, 0x68), 1160 + CMN_EVENT_CCHA(CMN_ANY, rdbyp_occ, 0x69), 1161 + CMN_EVENT_CCHA(CMN_ANY, wdb_occ, 0x6a), 1162 + CMN_EVENT_CCHA(CMN_ANY, snptrk_occ, 0x6b), 1163 + CMN_EVENT_CCHA(CMN_ANY, sdb_occ, 0x6c), 1164 + CMN_EVENT_CCHA(CMN_ANY, snphaz_occ, 0x6d), 1165 + CMN_EVENT_CCHA(CMN_ANY, reqtrk_alloc, 0x6e), 1166 + CMN_EVENT_CCHA(CMN_ANY, rdb_alloc, 0x6f), 1167 + CMN_EVENT_CCHA(CMN_ANY, rdbyp_alloc, 0x70), 1168 + CMN_EVENT_CCHA(CMN_ANY, wdb_alloc, 0x71), 1169 + CMN_EVENT_CCHA(CMN_ANY, snptrk_alloc, 0x72), 1170 + CMN_EVENT_CCHA(CMN_ANY, db_alloc, 0x73), 1171 + CMN_EVENT_CCHA(CMN_ANY, snphaz_alloc, 0x74), 1172 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_occ, 0x75), 1173 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_req_alloc, 0x76), 1174 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_occ, 0x77), 1175 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_req_alloc, 0x78), 1176 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_occ, 0x79), 1177 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_req_alloc, 0x7a), 1178 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_occ, 0x7b), 1179 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_reg_req_alloc, 0x7c), 1180 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_occ, 0x7d), 1181 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_rsvd_req_alloc, 0x7e), 1182 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_occ, 0x7f), 1183 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_dat_alloc, 0x80), 1184 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_occ, 0x81), 1185 + CMN_EVENT_CCHA(CMN_ANY, pb_rhu_pcie_dat_alloc, 0x82), 1186 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_occ, 0x83), 1187 + CMN_EVENT_CCHA(CMN_ANY, pb_pcie_wr_dat_alloc, 0x84), 1188 + CMN_EVENT_CCHA(CMNS3, chirsp1_up_stall, 0x85), 1196 1189 1197 1190 CMN_EVENT_CCLA(rx_cxs, 0x21), 1198 1191 CMN_EVENT_CCLA(tx_cxs, 0x22), ··· 1280 1271 struct device_attribute *attr, char *buf) 1281 1272 { 1282 1273 struct arm_cmn_format_attr *fmt = container_of(attr, typeof(*fmt), attr); 1283 - int lo = __ffs(fmt->field), hi = __fls(fmt->field); 1284 - 1285 - if (lo == hi) 1286 - return sysfs_emit(buf, "config:%d\n", lo); 1287 1274 1288 1275 if (!fmt->config) 1289 - return sysfs_emit(buf, "config:%d-%d\n", lo, hi); 1276 + return sysfs_emit(buf, "config:%*pbl\n", 64, &fmt->field); 1290 1277 1291 - return sysfs_emit(buf, "config%d:%d-%d\n", fmt->config, lo, hi); 1278 + return sysfs_emit(buf, "config%d:%*pbl\n", fmt->config, 64, &fmt->field); 1292 1279 } 1293 1280 1294 1281 #define _CMN_FORMAT_ATTR(_name, _cfg, _fld) \ ··· 1420 1415 static void arm_cmn_set_state(struct arm_cmn *cmn, u32 state) 1421 1416 { 1422 1417 if (!cmn->state) 1423 - writel_relaxed(0, cmn->dtc[0].base + CMN_DT_PMCR); 1418 + writel_relaxed(0, CMN_DT_PMCR(&cmn->dtc[0])); 1424 1419 cmn->state |= state; 1425 1420 } 1426 1421 ··· 1429 1424 cmn->state &= ~state; 1430 1425 if (!cmn->state) 1431 1426 writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, 1432 - cmn->dtc[0].base + CMN_DT_PMCR); 1427 + CMN_DT_PMCR(&cmn->dtc[0])); 1433 1428 } 1434 1429 1435 1430 static void arm_cmn_pmu_enable(struct pmu *pmu) ··· 1464 1459 1465 1460 static u64 arm_cmn_read_cc(struct arm_cmn_dtc *dtc) 1466 1461 { 1467 - u64 val = readq_relaxed(dtc->base + CMN_DT_PMCCNTR); 1462 + void __iomem *pmccntr = CMN_DT_PMCCNTR(dtc); 1463 + u64 val = readq_relaxed(pmccntr); 1468 1464 1469 - writeq_relaxed(CMN_CC_INIT, dtc->base + CMN_DT_PMCCNTR); 1465 + writeq_relaxed(CMN_CC_INIT, pmccntr); 1470 1466 return (val - CMN_CC_INIT) & ((CMN_CC_INIT << 1) - 1); 1471 1467 } 1472 1468 1473 1469 static u32 arm_cmn_read_counter(struct arm_cmn_dtc *dtc, int idx) 1474 1470 { 1475 - u32 val, pmevcnt = CMN_DT_PMEVCNT(idx); 1471 + void __iomem *pmevcnt = CMN_DT_PMEVCNT(dtc, idx); 1472 + u32 val = readl_relaxed(pmevcnt); 1476 1473 1477 - val = readl_relaxed(dtc->base + pmevcnt); 1478 - writel_relaxed(CMN_COUNTER_INIT, dtc->base + pmevcnt); 1474 + writel_relaxed(CMN_COUNTER_INIT, pmevcnt); 1479 1475 return val - CMN_COUNTER_INIT; 1480 1476 } 1481 1477 ··· 1487 1481 u64 count; 1488 1482 1489 1483 for_each_hw_dtc_idx(hw, i, idx) { 1490 - writel_relaxed(CMN_COUNTER_INIT, cmn->dtc[i].base + CMN_DT_PMEVCNT(idx)); 1484 + writel_relaxed(CMN_COUNTER_INIT, CMN_DT_PMEVCNT(&cmn->dtc[i], idx)); 1491 1485 cmn->dtc[i].counters[idx] = event; 1492 1486 } 1493 1487 ··· 1570 1564 int i; 1571 1565 1572 1566 if (type == CMN_TYPE_DTC) { 1573 - i = hw->dtc_idx[0]; 1574 - writeq_relaxed(CMN_CC_INIT, cmn->dtc[i].base + CMN_DT_PMCCNTR); 1575 - cmn->dtc[i].cc_active = true; 1567 + struct arm_cmn_dtc *dtc = cmn->dtc + hw->dtc_idx[0]; 1568 + 1569 + writel_relaxed(CMN_DT_DTC_CTL_DT_EN | CMN_DT_DTC_CTL_CG_DISABLE, 1570 + dtc->base + CMN_DT_DTC_CTL); 1571 + writeq_relaxed(CMN_CC_INIT, CMN_DT_PMCCNTR(dtc)); 1572 + dtc->cc_active = true; 1576 1573 } else if (type == CMN_TYPE_WP) { 1577 1574 u64 val = CMN_EVENT_WP_VAL(event); 1578 1575 u64 mask = CMN_EVENT_WP_MASK(event); ··· 1604 1595 int i; 1605 1596 1606 1597 if (type == CMN_TYPE_DTC) { 1607 - i = hw->dtc_idx[0]; 1608 - cmn->dtc[i].cc_active = false; 1598 + struct arm_cmn_dtc *dtc = cmn->dtc + hw->dtc_idx[0]; 1599 + 1600 + dtc->cc_active = false; 1601 + writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL); 1609 1602 } else if (type == CMN_TYPE_WP) { 1610 1603 for_each_hw_dn(hw, dn, i) { 1611 1604 void __iomem *base = dn->pmu_base + CMN_DTM_OFFSET(hw->dtm_offset); ··· 1795 1784 /* ...but the DTM may depend on which port we're watching */ 1796 1785 if (cmn->multi_dtm) 1797 1786 hw->dtm_offset = CMN_EVENT_WP_DEV_SEL(event) / 2; 1798 - } else if (type == CMN_TYPE_XP && cmn->part == PART_CMN700) { 1787 + } else if (type == CMN_TYPE_XP && 1788 + (cmn->part == PART_CMN700 || cmn->part == PART_CMN_S3)) { 1799 1789 hw->wide_sel = true; 1800 1790 } 1801 1791 ··· 1827 1815 } 1828 1816 1829 1817 if (!hw->num_dns) { 1830 - struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, nodeid); 1831 - 1832 - dev_dbg(cmn->dev, "invalid node 0x%x (%d,%d,%d,%d) type 0x%x\n", 1833 - nodeid, nid.x, nid.y, nid.port, nid.dev, type); 1818 + dev_dbg(cmn->dev, "invalid node 0x%x type 0x%x\n", nodeid, type); 1834 1819 return -EINVAL; 1835 1820 } 1836 1821 ··· 1930 1921 arm_cmn_claim_wp_idx(dtm, event, d, wp_idx, i); 1931 1922 writel_relaxed(cfg, dtm->base + CMN_DTM_WPn_CONFIG(wp_idx)); 1932 1923 } else { 1933 - struct arm_cmn_nodeid nid = arm_cmn_nid(cmn, dn->id); 1924 + struct arm_cmn_nodeid nid = arm_cmn_nid(dn); 1934 1925 1935 1926 if (cmn->multi_dtm) 1936 1927 nid.port %= 2; ··· 2019 2010 2020 2011 cmn = hlist_entry_safe(cpuhp_node, struct arm_cmn, cpuhp_node); 2021 2012 node = dev_to_node(cmn->dev); 2022 - if (node != NUMA_NO_NODE && cpu_to_node(cmn->cpu) != node && cpu_to_node(cpu) == node) 2013 + if (cpu_to_node(cmn->cpu) != node && cpu_to_node(cpu) == node) 2023 2014 arm_cmn_migrate(cmn, cpu); 2024 2015 return 0; 2025 2016 } ··· 2052 2043 irqreturn_t ret = IRQ_NONE; 2053 2044 2054 2045 for (;;) { 2055 - u32 status = readl_relaxed(dtc->base + CMN_DT_PMOVSR); 2046 + u32 status = readl_relaxed(CMN_DT_PMOVSR(dtc)); 2056 2047 u64 delta; 2057 2048 int i; 2058 2049 ··· 2074 2065 } 2075 2066 } 2076 2067 2077 - writel_relaxed(status, dtc->base + CMN_DT_PMOVSR_CLR); 2068 + writel_relaxed(status, CMN_DT_PMOVSR_CLR(dtc)); 2078 2069 2079 2070 if (!dtc->irq_friend) 2080 2071 return ret; ··· 2128 2119 { 2129 2120 struct arm_cmn_dtc *dtc = cmn->dtc + idx; 2130 2121 2131 - dtc->base = dn->pmu_base - CMN_PMU_OFFSET; 2122 + dtc->pmu_base = dn->pmu_base; 2123 + dtc->base = dtc->pmu_base - arm_cmn_pmu_offset(cmn, dn); 2132 2124 dtc->irq = platform_get_irq(to_platform_device(cmn->dev), idx); 2133 2125 if (dtc->irq < 0) 2134 2126 return dtc->irq; 2135 2127 2136 2128 writel_relaxed(CMN_DT_DTC_CTL_DT_EN, dtc->base + CMN_DT_DTC_CTL); 2137 - writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, dtc->base + CMN_DT_PMCR); 2138 - writeq_relaxed(0, dtc->base + CMN_DT_PMCCNTR); 2139 - writel_relaxed(0x1ff, dtc->base + CMN_DT_PMOVSR_CLR); 2129 + writel_relaxed(CMN_DT_PMCR_PMU_EN | CMN_DT_PMCR_OVFL_INTR_EN, CMN_DT_PMCR(dtc)); 2130 + writeq_relaxed(0, CMN_DT_PMCCNTR(dtc)); 2131 + writel_relaxed(0x1ff, CMN_DT_PMOVSR_CLR(dtc)); 2140 2132 2141 2133 return 0; 2142 2134 } ··· 2178 2168 continue; 2179 2169 2180 2170 xp = arm_cmn_node_to_xp(cmn, dn); 2171 + dn->portid_bits = xp->portid_bits; 2172 + dn->deviceid_bits = xp->deviceid_bits; 2181 2173 dn->dtc = xp->dtc; 2182 2174 dn->dtm = xp->dtm; 2183 2175 if (cmn->multi_dtm) 2184 - dn->dtm += arm_cmn_nid(cmn, dn->id).port / 2; 2176 + dn->dtm += arm_cmn_nid(dn).port / 2; 2185 2177 2186 2178 if (dn->type == CMN_TYPE_DTC) { 2187 2179 int err = arm_cmn_init_dtc(cmn, dn, dtc_idx++); ··· 2225 2213 node->id = FIELD_GET(CMN_NI_NODE_ID, reg); 2226 2214 node->logid = FIELD_GET(CMN_NI_LOGICAL_ID, reg); 2227 2215 2228 - node->pmu_base = cmn->base + offset + CMN_PMU_OFFSET; 2216 + node->pmu_base = cmn->base + offset + arm_cmn_pmu_offset(cmn, node); 2229 2217 2230 2218 if (node->type == CMN_TYPE_CFG) 2231 2219 level = 0; ··· 2283 2271 reg = readl_relaxed(cfg_region + CMN_CFGM_PERIPH_ID_23); 2284 2272 cmn->rev = FIELD_GET(CMN_CFGM_PID2_REVISION, reg); 2285 2273 2274 + /* 2275 + * With the device isolation feature, if firmware has neglected to enable 2276 + * an XP port then we risk locking up if we try to access anything behind 2277 + * it; however we also have no way to tell from Non-Secure whether any 2278 + * given port is disabled or not, so the only way to win is not to play... 2279 + */ 2286 2280 reg = readq_relaxed(cfg_region + CMN_CFGM_INFO_GLOBAL); 2281 + if (reg & CMN_INFO_DEVICE_ISO_ENABLE) { 2282 + dev_err(cmn->dev, "Device isolation enabled, not continuing due to risk of lockup\n"); 2283 + return -ENODEV; 2284 + } 2287 2285 cmn->multi_dtm = reg & CMN_INFO_MULTIPLE_DTM_EN; 2288 2286 cmn->rsp_vc_num = FIELD_GET(CMN_INFO_RSP_VC_NUM, reg); 2289 2287 cmn->dat_vc_num = FIELD_GET(CMN_INFO_DAT_VC_NUM, reg); ··· 2363 2341 arm_cmn_init_dtm(dtm++, xp, 0); 2364 2342 /* 2365 2343 * Keeping track of connected ports will let us filter out 2366 - * unnecessary XP events easily. We can also reliably infer the 2367 - * "extra device ports" configuration for the node ID format 2368 - * from this, since in that case we will see at least one XP 2369 - * with port 2 connected, for the HN-D. 2344 + * unnecessary XP events easily, and also infer the per-XP 2345 + * part of the node ID format. 2370 2346 */ 2371 2347 for (int p = 0; p < CMN_MAX_PORTS; p++) 2372 2348 if (arm_cmn_device_connect_info(cmn, xp, p)) 2373 2349 xp_ports |= BIT(p); 2374 2350 2375 - if (cmn->multi_dtm && (xp_ports & 0xc)) 2351 + if (cmn->num_xps == 1) { 2352 + xp->portid_bits = 3; 2353 + xp->deviceid_bits = 2; 2354 + } else if (xp_ports > 0x3) { 2355 + xp->portid_bits = 2; 2356 + xp->deviceid_bits = 1; 2357 + } else { 2358 + xp->portid_bits = 1; 2359 + xp->deviceid_bits = 2; 2360 + } 2361 + 2362 + if (cmn->multi_dtm && (xp_ports > 0x3)) 2376 2363 arm_cmn_init_dtm(dtm++, xp, 1); 2377 - if (cmn->multi_dtm && (xp_ports & 0x30)) 2364 + if (cmn->multi_dtm && (xp_ports > 0xf)) 2378 2365 arm_cmn_init_dtm(dtm++, xp, 2); 2379 2366 2380 2367 cmn->ports_used |= xp_ports; ··· 2438 2407 case CMN_TYPE_CXHA: 2439 2408 case CMN_TYPE_CCRA: 2440 2409 case CMN_TYPE_CCHA: 2441 - case CMN_TYPE_CCLA: 2442 2410 case CMN_TYPE_HNS: 2411 + dn++; 2412 + break; 2413 + case CMN_TYPE_CCLA: 2414 + dn->pmu_base += CMN_CCLA_PMU_EVENT_SEL; 2443 2415 dn++; 2444 2416 break; 2445 2417 /* Nothing to see here */ ··· 2452 2418 case CMN_TYPE_CXLA: 2453 2419 case CMN_TYPE_HNS_MPAM_S: 2454 2420 case CMN_TYPE_HNS_MPAM_NS: 2421 + case CMN_TYPE_APB: 2455 2422 break; 2456 2423 /* 2457 2424 * Split "optimised" combination nodes into separate ··· 2463 2428 case CMN_TYPE_HNP: 2464 2429 case CMN_TYPE_CCLA_RNI: 2465 2430 dn[1] = dn[0]; 2466 - dn[0].pmu_base += CMN_HNP_PMU_EVENT_SEL; 2431 + dn[0].pmu_base += CMN_CCLA_PMU_EVENT_SEL; 2467 2432 dn[1].type = arm_cmn_subtype(dn->type); 2468 2433 dn += 2; 2469 2434 break; ··· 2638 2603 { .compatible = "arm,cmn-600", .data = (void *)PART_CMN600 }, 2639 2604 { .compatible = "arm,cmn-650" }, 2640 2605 { .compatible = "arm,cmn-700" }, 2606 + { .compatible = "arm,cmn-s3" }, 2641 2607 { .compatible = "arm,ci-700" }, 2642 2608 {} 2643 2609 };
+781
drivers/perf/arm-ni.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + // Copyright (C) 2022-2024 Arm Limited 3 + // NI-700 Network-on-Chip PMU driver 4 + 5 + #include <linux/acpi.h> 6 + #include <linux/bitfield.h> 7 + #include <linux/interrupt.h> 8 + #include <linux/io.h> 9 + #include <linux/io-64-nonatomic-lo-hi.h> 10 + #include <linux/kernel.h> 11 + #include <linux/module.h> 12 + #include <linux/of.h> 13 + #include <linux/perf_event.h> 14 + #include <linux/platform_device.h> 15 + #include <linux/slab.h> 16 + 17 + /* Common registers */ 18 + #define NI_NODE_TYPE 0x000 19 + #define NI_NODE_TYPE_NODE_ID GENMASK(31, 16) 20 + #define NI_NODE_TYPE_NODE_TYPE GENMASK(15, 0) 21 + 22 + #define NI_CHILD_NODE_INFO 0x004 23 + #define NI_CHILD_PTR(n) (0x008 + (n) * 4) 24 + 25 + #define NI700_PMUSELA 0x00c 26 + 27 + /* Config node */ 28 + #define NI_PERIPHERAL_ID0 0xfe0 29 + #define NI_PIDR0_PART_7_0 GENMASK(7, 0) 30 + #define NI_PERIPHERAL_ID1 0xfe4 31 + #define NI_PIDR1_PART_11_8 GENMASK(3, 0) 32 + #define NI_PERIPHERAL_ID2 0xfe8 33 + #define NI_PIDR2_VERSION GENMASK(7, 4) 34 + 35 + /* PMU node */ 36 + #define NI_PMEVCNTR(n) (0x008 + (n) * 8) 37 + #define NI_PMCCNTR_L 0x0f8 38 + #define NI_PMCCNTR_U 0x0fc 39 + #define NI_PMEVTYPER(n) (0x400 + (n) * 4) 40 + #define NI_PMEVTYPER_NODE_TYPE GENMASK(12, 9) 41 + #define NI_PMEVTYPER_NODE_ID GENMASK(8, 0) 42 + #define NI_PMCNTENSET 0xc00 43 + #define NI_PMCNTENCLR 0xc20 44 + #define NI_PMINTENSET 0xc40 45 + #define NI_PMINTENCLR 0xc60 46 + #define NI_PMOVSCLR 0xc80 47 + #define NI_PMOVSSET 0xcc0 48 + #define NI_PMCFGR 0xe00 49 + #define NI_PMCR 0xe04 50 + #define NI_PMCR_RESET_CCNT BIT(2) 51 + #define NI_PMCR_RESET_EVCNT BIT(1) 52 + #define NI_PMCR_ENABLE BIT(0) 53 + 54 + #define NI_NUM_COUNTERS 8 55 + #define NI_CCNT_IDX 31 56 + 57 + /* Event attributes */ 58 + #define NI_CONFIG_TYPE GENMASK_ULL(15, 0) 59 + #define NI_CONFIG_NODEID GENMASK_ULL(31, 16) 60 + #define NI_CONFIG_EVENTID GENMASK_ULL(47, 32) 61 + 62 + #define NI_EVENT_TYPE(event) FIELD_GET(NI_CONFIG_TYPE, (event)->attr.config) 63 + #define NI_EVENT_NODEID(event) FIELD_GET(NI_CONFIG_NODEID, (event)->attr.config) 64 + #define NI_EVENT_EVENTID(event) FIELD_GET(NI_CONFIG_EVENTID, (event)->attr.config) 65 + 66 + enum ni_part { 67 + PART_NI_700 = 0x43b, 68 + PART_NI_710AE = 0x43d, 69 + }; 70 + 71 + enum ni_node_type { 72 + NI_GLOBAL, 73 + NI_VOLTAGE, 74 + NI_POWER, 75 + NI_CLOCK, 76 + NI_ASNI, 77 + NI_AMNI, 78 + NI_PMU, 79 + NI_HSNI, 80 + NI_HMNI, 81 + NI_PMNI, 82 + }; 83 + 84 + struct arm_ni_node { 85 + void __iomem *base; 86 + enum ni_node_type type; 87 + u16 id; 88 + u32 num_components; 89 + }; 90 + 91 + struct arm_ni_unit { 92 + void __iomem *pmusela; 93 + enum ni_node_type type; 94 + u16 id; 95 + bool ns; 96 + union { 97 + __le64 pmusel; 98 + u8 event[8]; 99 + }; 100 + }; 101 + 102 + struct arm_ni_cd { 103 + void __iomem *pmu_base; 104 + u16 id; 105 + int num_units; 106 + int irq; 107 + int cpu; 108 + struct hlist_node cpuhp_node; 109 + struct pmu pmu; 110 + struct arm_ni_unit *units; 111 + struct perf_event *evcnt[NI_NUM_COUNTERS]; 112 + struct perf_event *ccnt; 113 + }; 114 + 115 + struct arm_ni { 116 + struct device *dev; 117 + void __iomem *base; 118 + enum ni_part part; 119 + int id; 120 + int num_cds; 121 + struct arm_ni_cd cds[] __counted_by(num_cds); 122 + }; 123 + 124 + #define cd_to_ni(cd) container_of((cd), struct arm_ni, cds[(cd)->id]) 125 + #define pmu_to_cd(p) container_of((p), struct arm_ni_cd, pmu) 126 + 127 + #define cd_for_each_unit(cd, u) \ 128 + for (struct arm_ni_unit *u = cd->units; u < cd->units + cd->num_units; u++) 129 + 130 + static int arm_ni_hp_state; 131 + 132 + struct arm_ni_event_attr { 133 + struct device_attribute attr; 134 + enum ni_node_type type; 135 + }; 136 + 137 + #define NI_EVENT_ATTR(_name, _type) \ 138 + (&((struct arm_ni_event_attr[]) {{ \ 139 + .attr = __ATTR(_name, 0444, arm_ni_event_show, NULL), \ 140 + .type = _type, \ 141 + }})[0].attr.attr) 142 + 143 + static ssize_t arm_ni_event_show(struct device *dev, 144 + struct device_attribute *attr, char *buf) 145 + { 146 + struct arm_ni_event_attr *eattr = container_of(attr, typeof(*eattr), attr); 147 + 148 + if (eattr->type == NI_PMU) 149 + return sysfs_emit(buf, "type=0x%x\n", eattr->type); 150 + 151 + return sysfs_emit(buf, "type=0x%x,eventid=?,nodeid=?\n", eattr->type); 152 + } 153 + 154 + static umode_t arm_ni_event_attr_is_visible(struct kobject *kobj, 155 + struct attribute *attr, int unused) 156 + { 157 + struct device *dev = kobj_to_dev(kobj); 158 + struct arm_ni_cd *cd = pmu_to_cd(dev_get_drvdata(dev)); 159 + struct arm_ni_event_attr *eattr; 160 + 161 + eattr = container_of(attr, typeof(*eattr), attr.attr); 162 + 163 + cd_for_each_unit(cd, unit) { 164 + if (unit->type == eattr->type && unit->ns) 165 + return attr->mode; 166 + } 167 + 168 + return 0; 169 + } 170 + 171 + static struct attribute *arm_ni_event_attrs[] = { 172 + NI_EVENT_ATTR(asni, NI_ASNI), 173 + NI_EVENT_ATTR(amni, NI_AMNI), 174 + NI_EVENT_ATTR(cycles, NI_PMU), 175 + NI_EVENT_ATTR(hsni, NI_HSNI), 176 + NI_EVENT_ATTR(hmni, NI_HMNI), 177 + NI_EVENT_ATTR(pmni, NI_PMNI), 178 + NULL 179 + }; 180 + 181 + static const struct attribute_group arm_ni_event_attrs_group = { 182 + .name = "events", 183 + .attrs = arm_ni_event_attrs, 184 + .is_visible = arm_ni_event_attr_is_visible, 185 + }; 186 + 187 + struct arm_ni_format_attr { 188 + struct device_attribute attr; 189 + u64 field; 190 + }; 191 + 192 + #define NI_FORMAT_ATTR(_name, _fld) \ 193 + (&((struct arm_ni_format_attr[]) {{ \ 194 + .attr = __ATTR(_name, 0444, arm_ni_format_show, NULL), \ 195 + .field = _fld, \ 196 + }})[0].attr.attr) 197 + 198 + static ssize_t arm_ni_format_show(struct device *dev, 199 + struct device_attribute *attr, char *buf) 200 + { 201 + struct arm_ni_format_attr *fmt = container_of(attr, typeof(*fmt), attr); 202 + 203 + return sysfs_emit(buf, "config:%*pbl\n", 64, &fmt->field); 204 + } 205 + 206 + static struct attribute *arm_ni_format_attrs[] = { 207 + NI_FORMAT_ATTR(type, NI_CONFIG_TYPE), 208 + NI_FORMAT_ATTR(nodeid, NI_CONFIG_NODEID), 209 + NI_FORMAT_ATTR(eventid, NI_CONFIG_EVENTID), 210 + NULL 211 + }; 212 + 213 + static const struct attribute_group arm_ni_format_attrs_group = { 214 + .name = "format", 215 + .attrs = arm_ni_format_attrs, 216 + }; 217 + 218 + static ssize_t arm_ni_cpumask_show(struct device *dev, 219 + struct device_attribute *attr, char *buf) 220 + { 221 + struct arm_ni_cd *cd = pmu_to_cd(dev_get_drvdata(dev)); 222 + 223 + return cpumap_print_to_pagebuf(true, buf, cpumask_of(cd->cpu)); 224 + } 225 + 226 + static struct device_attribute arm_ni_cpumask_attr = 227 + __ATTR(cpumask, 0444, arm_ni_cpumask_show, NULL); 228 + 229 + static ssize_t arm_ni_identifier_show(struct device *dev, 230 + struct device_attribute *attr, char *buf) 231 + { 232 + struct arm_ni *ni = cd_to_ni(pmu_to_cd(dev_get_drvdata(dev))); 233 + u32 reg = readl_relaxed(ni->base + NI_PERIPHERAL_ID2); 234 + int version = FIELD_GET(NI_PIDR2_VERSION, reg); 235 + 236 + return sysfs_emit(buf, "%03x%02x\n", ni->part, version); 237 + } 238 + 239 + static struct device_attribute arm_ni_identifier_attr = 240 + __ATTR(identifier, 0444, arm_ni_identifier_show, NULL); 241 + 242 + static struct attribute *arm_ni_other_attrs[] = { 243 + &arm_ni_cpumask_attr.attr, 244 + &arm_ni_identifier_attr.attr, 245 + NULL 246 + }; 247 + 248 + static const struct attribute_group arm_ni_other_attr_group = { 249 + .attrs = arm_ni_other_attrs, 250 + NULL 251 + }; 252 + 253 + static const struct attribute_group *arm_ni_attr_groups[] = { 254 + &arm_ni_event_attrs_group, 255 + &arm_ni_format_attrs_group, 256 + &arm_ni_other_attr_group, 257 + NULL 258 + }; 259 + 260 + static void arm_ni_pmu_enable(struct pmu *pmu) 261 + { 262 + writel_relaxed(NI_PMCR_ENABLE, pmu_to_cd(pmu)->pmu_base + NI_PMCR); 263 + } 264 + 265 + static void arm_ni_pmu_disable(struct pmu *pmu) 266 + { 267 + writel_relaxed(0, pmu_to_cd(pmu)->pmu_base + NI_PMCR); 268 + } 269 + 270 + struct arm_ni_val { 271 + unsigned int evcnt; 272 + unsigned int ccnt; 273 + }; 274 + 275 + static bool arm_ni_val_count_event(struct perf_event *evt, struct arm_ni_val *val) 276 + { 277 + if (is_software_event(evt)) 278 + return true; 279 + 280 + if (NI_EVENT_TYPE(evt) == NI_PMU) { 281 + val->ccnt++; 282 + return val->ccnt <= 1; 283 + } 284 + 285 + val->evcnt++; 286 + return val->evcnt <= NI_NUM_COUNTERS; 287 + } 288 + 289 + static int arm_ni_validate_group(struct perf_event *event) 290 + { 291 + struct perf_event *sibling, *leader = event->group_leader; 292 + struct arm_ni_val val = { 0 }; 293 + 294 + if (leader == event) 295 + return 0; 296 + 297 + arm_ni_val_count_event(event, &val); 298 + if (!arm_ni_val_count_event(leader, &val)) 299 + return -EINVAL; 300 + 301 + for_each_sibling_event(sibling, leader) { 302 + if (!arm_ni_val_count_event(sibling, &val)) 303 + return -EINVAL; 304 + } 305 + return 0; 306 + } 307 + 308 + static int arm_ni_event_init(struct perf_event *event) 309 + { 310 + struct arm_ni_cd *cd = pmu_to_cd(event->pmu); 311 + 312 + if (event->attr.type != event->pmu->type) 313 + return -ENOENT; 314 + 315 + if (is_sampling_event(event)) 316 + return -EINVAL; 317 + 318 + event->cpu = cd->cpu; 319 + if (NI_EVENT_TYPE(event) == NI_PMU) 320 + return arm_ni_validate_group(event); 321 + 322 + cd_for_each_unit(cd, unit) { 323 + if (unit->type == NI_EVENT_TYPE(event) && 324 + unit->id == NI_EVENT_NODEID(event) && unit->ns) { 325 + event->hw.config_base = (unsigned long)unit; 326 + return arm_ni_validate_group(event); 327 + } 328 + } 329 + return -EINVAL; 330 + } 331 + 332 + static u64 arm_ni_read_ccnt(struct arm_ni_cd *cd) 333 + { 334 + u64 l, u_old, u_new; 335 + int retries = 3; /* 1st time unlucky, 2nd improbable, 3rd just broken */ 336 + 337 + u_new = readl_relaxed(cd->pmu_base + NI_PMCCNTR_U); 338 + do { 339 + u_old = u_new; 340 + l = readl_relaxed(cd->pmu_base + NI_PMCCNTR_L); 341 + u_new = readl_relaxed(cd->pmu_base + NI_PMCCNTR_U); 342 + } while (u_new != u_old && --retries); 343 + WARN_ON(!retries); 344 + 345 + return (u_new << 32) | l; 346 + } 347 + 348 + static void arm_ni_event_read(struct perf_event *event) 349 + { 350 + struct arm_ni_cd *cd = pmu_to_cd(event->pmu); 351 + struct hw_perf_event *hw = &event->hw; 352 + u64 count, prev; 353 + bool ccnt = hw->idx == NI_CCNT_IDX; 354 + 355 + do { 356 + prev = local64_read(&hw->prev_count); 357 + if (ccnt) 358 + count = arm_ni_read_ccnt(cd); 359 + else 360 + count = readl_relaxed(cd->pmu_base + NI_PMEVCNTR(hw->idx)); 361 + } while (local64_cmpxchg(&hw->prev_count, prev, count) != prev); 362 + 363 + count -= prev; 364 + if (!ccnt) 365 + count = (u32)count; 366 + local64_add(count, &event->count); 367 + } 368 + 369 + static void arm_ni_event_start(struct perf_event *event, int flags) 370 + { 371 + struct arm_ni_cd *cd = pmu_to_cd(event->pmu); 372 + 373 + writel_relaxed(1U << event->hw.idx, cd->pmu_base + NI_PMCNTENSET); 374 + } 375 + 376 + static void arm_ni_event_stop(struct perf_event *event, int flags) 377 + { 378 + struct arm_ni_cd *cd = pmu_to_cd(event->pmu); 379 + 380 + writel_relaxed(1U << event->hw.idx, cd->pmu_base + NI_PMCNTENCLR); 381 + if (flags & PERF_EF_UPDATE) 382 + arm_ni_event_read(event); 383 + } 384 + 385 + static void arm_ni_init_ccnt(struct arm_ni_cd *cd) 386 + { 387 + local64_set(&cd->ccnt->hw.prev_count, S64_MIN); 388 + lo_hi_writeq_relaxed(S64_MIN, cd->pmu_base + NI_PMCCNTR_L); 389 + } 390 + 391 + static void arm_ni_init_evcnt(struct arm_ni_cd *cd, int idx) 392 + { 393 + local64_set(&cd->evcnt[idx]->hw.prev_count, S32_MIN); 394 + writel_relaxed(S32_MIN, cd->pmu_base + NI_PMEVCNTR(idx)); 395 + } 396 + 397 + static int arm_ni_event_add(struct perf_event *event, int flags) 398 + { 399 + struct arm_ni_cd *cd = pmu_to_cd(event->pmu); 400 + struct hw_perf_event *hw = &event->hw; 401 + struct arm_ni_unit *unit; 402 + enum ni_node_type type = NI_EVENT_TYPE(event); 403 + u32 reg; 404 + 405 + if (type == NI_PMU) { 406 + if (cd->ccnt) 407 + return -ENOSPC; 408 + hw->idx = NI_CCNT_IDX; 409 + cd->ccnt = event; 410 + arm_ni_init_ccnt(cd); 411 + } else { 412 + hw->idx = 0; 413 + while (cd->evcnt[hw->idx]) { 414 + if (++hw->idx == NI_NUM_COUNTERS) 415 + return -ENOSPC; 416 + } 417 + cd->evcnt[hw->idx] = event; 418 + unit = (void *)hw->config_base; 419 + unit->event[hw->idx] = NI_EVENT_EVENTID(event); 420 + arm_ni_init_evcnt(cd, hw->idx); 421 + lo_hi_writeq_relaxed(le64_to_cpu(unit->pmusel), unit->pmusela); 422 + 423 + reg = FIELD_PREP(NI_PMEVTYPER_NODE_TYPE, type) | 424 + FIELD_PREP(NI_PMEVTYPER_NODE_ID, NI_EVENT_NODEID(event)); 425 + writel_relaxed(reg, cd->pmu_base + NI_PMEVTYPER(hw->idx)); 426 + } 427 + if (flags & PERF_EF_START) 428 + arm_ni_event_start(event, 0); 429 + return 0; 430 + } 431 + 432 + static void arm_ni_event_del(struct perf_event *event, int flags) 433 + { 434 + struct arm_ni_cd *cd = pmu_to_cd(event->pmu); 435 + struct hw_perf_event *hw = &event->hw; 436 + 437 + arm_ni_event_stop(event, PERF_EF_UPDATE); 438 + 439 + if (hw->idx == NI_CCNT_IDX) 440 + cd->ccnt = NULL; 441 + else 442 + cd->evcnt[hw->idx] = NULL; 443 + } 444 + 445 + static irqreturn_t arm_ni_handle_irq(int irq, void *dev_id) 446 + { 447 + struct arm_ni_cd *cd = dev_id; 448 + irqreturn_t ret = IRQ_NONE; 449 + u32 reg = readl_relaxed(cd->pmu_base + NI_PMOVSCLR); 450 + 451 + if (reg & (1U << NI_CCNT_IDX)) { 452 + ret = IRQ_HANDLED; 453 + if (!(WARN_ON(!cd->ccnt))) { 454 + arm_ni_event_read(cd->ccnt); 455 + arm_ni_init_ccnt(cd); 456 + } 457 + } 458 + for (int i = 0; i < NI_NUM_COUNTERS; i++) { 459 + if (!(reg & (1U << i))) 460 + continue; 461 + ret = IRQ_HANDLED; 462 + if (!(WARN_ON(!cd->evcnt[i]))) { 463 + arm_ni_event_read(cd->evcnt[i]); 464 + arm_ni_init_evcnt(cd, i); 465 + } 466 + } 467 + writel_relaxed(reg, cd->pmu_base + NI_PMOVSCLR); 468 + return ret; 469 + } 470 + 471 + static int arm_ni_init_cd(struct arm_ni *ni, struct arm_ni_node *node, u64 res_start) 472 + { 473 + struct arm_ni_cd *cd = ni->cds + node->id; 474 + const char *name; 475 + int err; 476 + 477 + cd->id = node->id; 478 + cd->num_units = node->num_components; 479 + cd->units = devm_kcalloc(ni->dev, cd->num_units, sizeof(*(cd->units)), GFP_KERNEL); 480 + if (!cd->units) 481 + return -ENOMEM; 482 + 483 + for (int i = 0; i < cd->num_units; i++) { 484 + u32 reg = readl_relaxed(node->base + NI_CHILD_PTR(i)); 485 + void __iomem *unit_base = ni->base + reg; 486 + struct arm_ni_unit *unit = cd->units + i; 487 + 488 + reg = readl_relaxed(unit_base + NI_NODE_TYPE); 489 + unit->type = FIELD_GET(NI_NODE_TYPE_NODE_TYPE, reg); 490 + unit->id = FIELD_GET(NI_NODE_TYPE_NODE_ID, reg); 491 + 492 + switch (unit->type) { 493 + case NI_PMU: 494 + reg = readl_relaxed(unit_base + NI_PMCFGR); 495 + if (!reg) { 496 + dev_info(ni->dev, "No access to PMU %d\n", cd->id); 497 + devm_kfree(ni->dev, cd->units); 498 + return 0; 499 + } 500 + unit->ns = true; 501 + cd->pmu_base = unit_base; 502 + break; 503 + case NI_ASNI: 504 + case NI_AMNI: 505 + case NI_HSNI: 506 + case NI_HMNI: 507 + case NI_PMNI: 508 + unit->pmusela = unit_base + NI700_PMUSELA; 509 + writel_relaxed(1, unit->pmusela); 510 + if (readl_relaxed(unit->pmusela) != 1) 511 + dev_info(ni->dev, "No access to node 0x%04x%04x\n", unit->id, unit->type); 512 + else 513 + unit->ns = true; 514 + break; 515 + default: 516 + /* 517 + * e.g. FMU - thankfully bits 3:2 of FMU_ERR_FR0 are RES0 so 518 + * can't alias any of the leaf node types we're looking for. 519 + */ 520 + dev_dbg(ni->dev, "Mystery node 0x%04x%04x\n", unit->id, unit->type); 521 + break; 522 + } 523 + } 524 + 525 + res_start += cd->pmu_base - ni->base; 526 + if (!devm_request_mem_region(ni->dev, res_start, SZ_4K, dev_name(ni->dev))) { 527 + dev_err(ni->dev, "Failed to request PMU region 0x%llx\n", res_start); 528 + return -EBUSY; 529 + } 530 + 531 + writel_relaxed(NI_PMCR_RESET_CCNT | NI_PMCR_RESET_EVCNT, 532 + cd->pmu_base + NI_PMCR); 533 + writel_relaxed(U32_MAX, cd->pmu_base + NI_PMCNTENCLR); 534 + writel_relaxed(U32_MAX, cd->pmu_base + NI_PMOVSCLR); 535 + writel_relaxed(U32_MAX, cd->pmu_base + NI_PMINTENSET); 536 + 537 + cd->irq = platform_get_irq(to_platform_device(ni->dev), cd->id); 538 + if (cd->irq < 0) 539 + return cd->irq; 540 + 541 + err = devm_request_irq(ni->dev, cd->irq, arm_ni_handle_irq, 542 + IRQF_NOBALANCING | IRQF_NO_THREAD, 543 + dev_name(ni->dev), cd); 544 + if (err) 545 + return err; 546 + 547 + cd->cpu = cpumask_local_spread(0, dev_to_node(ni->dev)); 548 + cd->pmu = (struct pmu) { 549 + .module = THIS_MODULE, 550 + .parent = ni->dev, 551 + .attr_groups = arm_ni_attr_groups, 552 + .capabilities = PERF_PMU_CAP_NO_EXCLUDE, 553 + .task_ctx_nr = perf_invalid_context, 554 + .pmu_enable = arm_ni_pmu_enable, 555 + .pmu_disable = arm_ni_pmu_disable, 556 + .event_init = arm_ni_event_init, 557 + .add = arm_ni_event_add, 558 + .del = arm_ni_event_del, 559 + .start = arm_ni_event_start, 560 + .stop = arm_ni_event_stop, 561 + .read = arm_ni_event_read, 562 + }; 563 + 564 + name = devm_kasprintf(ni->dev, GFP_KERNEL, "arm_ni_%d_cd_%d", ni->id, cd->id); 565 + if (!name) 566 + return -ENOMEM; 567 + 568 + err = cpuhp_state_add_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node); 569 + if (err) 570 + return err; 571 + 572 + err = perf_pmu_register(&cd->pmu, name, -1); 573 + if (err) 574 + cpuhp_state_remove_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node); 575 + 576 + return err; 577 + } 578 + 579 + static void arm_ni_probe_domain(void __iomem *base, struct arm_ni_node *node) 580 + { 581 + u32 reg = readl_relaxed(base + NI_NODE_TYPE); 582 + 583 + node->base = base; 584 + node->type = FIELD_GET(NI_NODE_TYPE_NODE_TYPE, reg); 585 + node->id = FIELD_GET(NI_NODE_TYPE_NODE_ID, reg); 586 + node->num_components = readl_relaxed(base + NI_CHILD_NODE_INFO); 587 + } 588 + 589 + static int arm_ni_probe(struct platform_device *pdev) 590 + { 591 + struct arm_ni_node cfg, vd, pd, cd; 592 + struct arm_ni *ni; 593 + struct resource *res; 594 + void __iomem *base; 595 + static atomic_t id; 596 + int num_cds; 597 + u32 reg, part; 598 + 599 + /* 600 + * We want to map the whole configuration space for ease of discovery, 601 + * but the PMU pages are the only ones for which we can honestly claim 602 + * exclusive ownership, so we'll request them explicitly once found. 603 + */ 604 + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 605 + base = devm_ioremap(&pdev->dev, res->start, resource_size(res)); 606 + if (!base) 607 + return -ENOMEM; 608 + 609 + arm_ni_probe_domain(base, &cfg); 610 + if (cfg.type != NI_GLOBAL) 611 + return -ENODEV; 612 + 613 + reg = readl_relaxed(cfg.base + NI_PERIPHERAL_ID0); 614 + part = FIELD_GET(NI_PIDR0_PART_7_0, reg); 615 + reg = readl_relaxed(cfg.base + NI_PERIPHERAL_ID1); 616 + part |= FIELD_GET(NI_PIDR1_PART_11_8, reg) << 8; 617 + 618 + switch (part) { 619 + case PART_NI_700: 620 + case PART_NI_710AE: 621 + break; 622 + default: 623 + dev_WARN(&pdev->dev, "Unknown part number: 0x%03x, this may go badly\n", part); 624 + break; 625 + } 626 + 627 + num_cds = 0; 628 + for (int v = 0; v < cfg.num_components; v++) { 629 + reg = readl_relaxed(cfg.base + NI_CHILD_PTR(v)); 630 + arm_ni_probe_domain(base + reg, &vd); 631 + for (int p = 0; p < vd.num_components; p++) { 632 + reg = readl_relaxed(vd.base + NI_CHILD_PTR(p)); 633 + arm_ni_probe_domain(base + reg, &pd); 634 + num_cds += pd.num_components; 635 + } 636 + } 637 + 638 + ni = devm_kzalloc(&pdev->dev, struct_size(ni, cds, num_cds), GFP_KERNEL); 639 + if (!ni) 640 + return -ENOMEM; 641 + 642 + ni->dev = &pdev->dev; 643 + ni->base = base; 644 + ni->num_cds = num_cds; 645 + ni->part = part; 646 + ni->id = atomic_fetch_inc(&id); 647 + 648 + for (int v = 0; v < cfg.num_components; v++) { 649 + reg = readl_relaxed(cfg.base + NI_CHILD_PTR(v)); 650 + arm_ni_probe_domain(base + reg, &vd); 651 + for (int p = 0; p < vd.num_components; p++) { 652 + reg = readl_relaxed(vd.base + NI_CHILD_PTR(p)); 653 + arm_ni_probe_domain(base + reg, &pd); 654 + for (int c = 0; c < pd.num_components; c++) { 655 + int ret; 656 + 657 + reg = readl_relaxed(pd.base + NI_CHILD_PTR(c)); 658 + arm_ni_probe_domain(base + reg, &cd); 659 + ret = arm_ni_init_cd(ni, &cd, res->start); 660 + if (ret) 661 + return ret; 662 + } 663 + } 664 + } 665 + 666 + return 0; 667 + } 668 + 669 + static void arm_ni_remove(struct platform_device *pdev) 670 + { 671 + struct arm_ni *ni = platform_get_drvdata(pdev); 672 + 673 + for (int i = 0; i < ni->num_cds; i++) { 674 + struct arm_ni_cd *cd = ni->cds + i; 675 + 676 + if (!cd->pmu_base) 677 + continue; 678 + 679 + writel_relaxed(0, cd->pmu_base + NI_PMCR); 680 + writel_relaxed(U32_MAX, cd->pmu_base + NI_PMINTENCLR); 681 + perf_pmu_unregister(&cd->pmu); 682 + cpuhp_state_remove_instance_nocalls(arm_ni_hp_state, &cd->cpuhp_node); 683 + } 684 + } 685 + 686 + #ifdef CONFIG_OF 687 + static const struct of_device_id arm_ni_of_match[] = { 688 + { .compatible = "arm,ni-700" }, 689 + {} 690 + }; 691 + MODULE_DEVICE_TABLE(of, arm_ni_of_match); 692 + #endif 693 + 694 + #ifdef CONFIG_ACPI 695 + static const struct acpi_device_id arm_ni_acpi_match[] = { 696 + { "ARMHCB70" }, 697 + {} 698 + }; 699 + MODULE_DEVICE_TABLE(acpi, arm_ni_acpi_match); 700 + #endif 701 + 702 + static struct platform_driver arm_ni_driver = { 703 + .driver = { 704 + .name = "arm-ni", 705 + .of_match_table = of_match_ptr(arm_ni_of_match), 706 + .acpi_match_table = ACPI_PTR(arm_ni_acpi_match), 707 + }, 708 + .probe = arm_ni_probe, 709 + .remove = arm_ni_remove, 710 + }; 711 + 712 + static void arm_ni_pmu_migrate(struct arm_ni_cd *cd, unsigned int cpu) 713 + { 714 + perf_pmu_migrate_context(&cd->pmu, cd->cpu, cpu); 715 + irq_set_affinity(cd->irq, cpumask_of(cpu)); 716 + cd->cpu = cpu; 717 + } 718 + 719 + static int arm_ni_pmu_online_cpu(unsigned int cpu, struct hlist_node *cpuhp_node) 720 + { 721 + struct arm_ni_cd *cd; 722 + int node; 723 + 724 + cd = hlist_entry_safe(cpuhp_node, struct arm_ni_cd, cpuhp_node); 725 + node = dev_to_node(cd_to_ni(cd)->dev); 726 + if (cpu_to_node(cd->cpu) != node && cpu_to_node(cpu) == node) 727 + arm_ni_pmu_migrate(cd, cpu); 728 + return 0; 729 + } 730 + 731 + static int arm_ni_pmu_offline_cpu(unsigned int cpu, struct hlist_node *cpuhp_node) 732 + { 733 + struct arm_ni_cd *cd; 734 + unsigned int target; 735 + int node; 736 + 737 + cd = hlist_entry_safe(cpuhp_node, struct arm_ni_cd, cpuhp_node); 738 + if (cpu != cd->cpu) 739 + return 0; 740 + 741 + node = dev_to_node(cd_to_ni(cd)->dev); 742 + target = cpumask_any_and_but(cpumask_of_node(node), cpu_online_mask, cpu); 743 + if (target >= nr_cpu_ids) 744 + target = cpumask_any_but(cpu_online_mask, cpu); 745 + 746 + if (target < nr_cpu_ids) 747 + arm_ni_pmu_migrate(cd, target); 748 + return 0; 749 + } 750 + 751 + static int __init arm_ni_init(void) 752 + { 753 + int ret; 754 + 755 + ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, 756 + "perf/arm/ni:online", 757 + arm_ni_pmu_online_cpu, 758 + arm_ni_pmu_offline_cpu); 759 + if (ret < 0) 760 + return ret; 761 + 762 + arm_ni_hp_state = ret; 763 + 764 + ret = platform_driver_register(&arm_ni_driver); 765 + if (ret) 766 + cpuhp_remove_multi_state(arm_ni_hp_state); 767 + return ret; 768 + } 769 + 770 + static void __exit arm_ni_exit(void) 771 + { 772 + platform_driver_unregister(&arm_ni_driver); 773 + cpuhp_remove_multi_state(arm_ni_hp_state); 774 + } 775 + 776 + module_init(arm_ni_init); 777 + module_exit(arm_ni_exit); 778 + 779 + MODULE_AUTHOR("Robin Murphy <robin.murphy@arm.com>"); 780 + MODULE_DESCRIPTION("Arm NI-700 PMU driver"); 781 + MODULE_LICENSE("GPL v2");
+6 -5
drivers/perf/arm_pmu.c
··· 522 522 { 523 523 struct arm_pmu *armpmu = to_arm_pmu(pmu); 524 524 struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events); 525 - bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events); 525 + bool enabled = !bitmap_empty(hw_events->used_mask, ARMPMU_MAX_HWEVENTS); 526 526 527 527 /* For task-bound events we may be called on other CPUs */ 528 528 if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus)) ··· 742 742 struct perf_event *event; 743 743 int idx; 744 744 745 - for (idx = 0; idx < armpmu->num_events; idx++) { 745 + for_each_set_bit(idx, armpmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 746 746 event = hw_events->events[idx]; 747 747 if (!event) 748 748 continue; ··· 772 772 { 773 773 struct arm_pmu *armpmu = container_of(b, struct arm_pmu, cpu_pm_nb); 774 774 struct pmu_hw_events *hw_events = this_cpu_ptr(armpmu->hw_events); 775 - bool enabled = !bitmap_empty(hw_events->used_mask, armpmu->num_events); 775 + bool enabled = !bitmap_empty(hw_events->used_mask, ARMPMU_MAX_HWEVENTS); 776 776 777 777 if (!cpumask_test_cpu(smp_processor_id(), &armpmu->supported_cpus)) 778 778 return NOTIFY_DONE; ··· 924 924 if (ret) 925 925 goto out_destroy; 926 926 927 - pr_info("enabled with %s PMU driver, %d counters available%s\n", 928 - pmu->name, pmu->num_events, 927 + pr_info("enabled with %s PMU driver, %d (%*pb) counters available%s\n", 928 + pmu->name, bitmap_weight(pmu->cntr_mask, ARMPMU_MAX_HWEVENTS), 929 + ARMPMU_MAX_HWEVENTS, &pmu->cntr_mask, 929 930 has_nmi ? ", using NMIs" : ""); 930 931 931 932 kvm_host_pmu_init(pmu);
+1 -1
drivers/perf/arm_pmu_platform.c
··· 59 59 60 60 static bool pmu_has_irq_affinity(struct device_node *node) 61 61 { 62 - return !!of_find_property(node, "interrupt-affinity", NULL); 62 + return of_property_present(node, "interrupt-affinity"); 63 63 } 64 64 65 65 static int pmu_parse_irq_affinity(struct device *dev, int i)
+75 -73
drivers/perf/arm_pmuv3.c
··· 452 452 }; 453 453 454 454 /* 455 - * Perf Events' indices 456 - */ 457 - #define ARMV8_IDX_CYCLE_COUNTER 0 458 - #define ARMV8_IDX_COUNTER0 1 459 - #define ARMV8_IDX_CYCLE_COUNTER_USER 32 460 - 461 - /* 462 455 * We unconditionally enable ARMv8.5-PMU long event counter support 463 456 * (64-bit events) where supported. Indicate if this arm_pmu has long 464 457 * event counter support. ··· 482 489 return !armv8pmu_event_has_user_read(event) && 483 490 armv8pmu_event_is_64bit(event) && 484 491 !armv8pmu_has_long_event(cpu_pmu) && 485 - (idx != ARMV8_IDX_CYCLE_COUNTER); 492 + (idx < ARMV8_PMU_MAX_GENERAL_COUNTERS); 486 493 } 487 494 488 495 /* 489 496 * ARMv8 low level PMU access 490 497 */ 491 - 492 - /* 493 - * Perf Event to low level counters mapping 494 - */ 495 - #define ARMV8_IDX_TO_COUNTER(x) \ 496 - (((x) - ARMV8_IDX_COUNTER0) & ARMV8_PMU_COUNTER_MASK) 497 - 498 498 static u64 armv8pmu_pmcr_read(void) 499 499 { 500 500 return read_pmcr(); ··· 500 514 write_pmcr(val); 501 515 } 502 516 503 - static int armv8pmu_has_overflowed(u32 pmovsr) 517 + static int armv8pmu_has_overflowed(u64 pmovsr) 504 518 { 505 - return pmovsr & ARMV8_PMU_OVERFLOWED_MASK; 519 + return !!(pmovsr & ARMV8_PMU_OVERFLOWED_MASK); 506 520 } 507 521 508 - static int armv8pmu_counter_has_overflowed(u32 pmnc, int idx) 522 + static int armv8pmu_counter_has_overflowed(u64 pmnc, int idx) 509 523 { 510 - return pmnc & BIT(ARMV8_IDX_TO_COUNTER(idx)); 524 + return !!(pmnc & BIT(idx)); 511 525 } 512 526 513 527 static u64 armv8pmu_read_evcntr(int idx) 514 528 { 515 - u32 counter = ARMV8_IDX_TO_COUNTER(idx); 516 - 517 - return read_pmevcntrn(counter); 529 + return read_pmevcntrn(idx); 518 530 } 519 531 520 532 static u64 armv8pmu_read_hw_counter(struct perf_event *event) ··· 541 557 return false; 542 558 543 559 if (armv8pmu_has_long_event(cpu_pmu) || 544 - idx == ARMV8_IDX_CYCLE_COUNTER) 560 + idx >= ARMV8_PMU_MAX_GENERAL_COUNTERS) 545 561 return true; 546 562 547 563 return false; ··· 569 585 int idx = hwc->idx; 570 586 u64 value; 571 587 572 - if (idx == ARMV8_IDX_CYCLE_COUNTER) 588 + if (idx == ARMV8_PMU_CYCLE_IDX) 573 589 value = read_pmccntr(); 590 + else if (idx == ARMV8_PMU_INSTR_IDX) 591 + value = read_pmicntr(); 574 592 else 575 593 value = armv8pmu_read_hw_counter(event); 576 594 ··· 581 595 582 596 static void armv8pmu_write_evcntr(int idx, u64 value) 583 597 { 584 - u32 counter = ARMV8_IDX_TO_COUNTER(idx); 585 - 586 - write_pmevcntrn(counter, value); 598 + write_pmevcntrn(idx, value); 587 599 } 588 600 589 601 static void armv8pmu_write_hw_counter(struct perf_event *event, ··· 604 620 605 621 value = armv8pmu_bias_long_counter(event, value); 606 622 607 - if (idx == ARMV8_IDX_CYCLE_COUNTER) 623 + if (idx == ARMV8_PMU_CYCLE_IDX) 608 624 write_pmccntr(value); 625 + else if (idx == ARMV8_PMU_INSTR_IDX) 626 + write_pmicntr(value); 609 627 else 610 628 armv8pmu_write_hw_counter(event, value); 611 629 } 612 630 613 631 static void armv8pmu_write_evtype(int idx, unsigned long val) 614 632 { 615 - u32 counter = ARMV8_IDX_TO_COUNTER(idx); 616 633 unsigned long mask = ARMV8_PMU_EVTYPE_EVENT | 617 634 ARMV8_PMU_INCLUDE_EL2 | 618 635 ARMV8_PMU_EXCLUDE_EL0 | ··· 623 638 mask |= ARMV8_PMU_EVTYPE_TC | ARMV8_PMU_EVTYPE_TH; 624 639 625 640 val &= mask; 626 - write_pmevtypern(counter, val); 641 + write_pmevtypern(idx, val); 627 642 } 628 643 629 644 static void armv8pmu_write_event_type(struct perf_event *event) ··· 643 658 armv8pmu_write_evtype(idx - 1, hwc->config_base); 644 659 armv8pmu_write_evtype(idx, chain_evt); 645 660 } else { 646 - if (idx == ARMV8_IDX_CYCLE_COUNTER) 661 + if (idx == ARMV8_PMU_CYCLE_IDX) 647 662 write_pmccfiltr(hwc->config_base); 663 + else if (idx == ARMV8_PMU_INSTR_IDX) 664 + write_pmicfiltr(hwc->config_base); 648 665 else 649 666 armv8pmu_write_evtype(idx, hwc->config_base); 650 667 } 651 668 } 652 669 653 - static u32 armv8pmu_event_cnten_mask(struct perf_event *event) 670 + static u64 armv8pmu_event_cnten_mask(struct perf_event *event) 654 671 { 655 - int counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); 656 - u32 mask = BIT(counter); 672 + int counter = event->hw.idx; 673 + u64 mask = BIT(counter); 657 674 658 675 if (armv8pmu_event_is_chained(event)) 659 676 mask |= BIT(counter - 1); 660 677 return mask; 661 678 } 662 679 663 - static void armv8pmu_enable_counter(u32 mask) 680 + static void armv8pmu_enable_counter(u64 mask) 664 681 { 665 682 /* 666 683 * Make sure event configuration register writes are visible before we ··· 675 688 static void armv8pmu_enable_event_counter(struct perf_event *event) 676 689 { 677 690 struct perf_event_attr *attr = &event->attr; 678 - u32 mask = armv8pmu_event_cnten_mask(event); 691 + u64 mask = armv8pmu_event_cnten_mask(event); 679 692 680 693 kvm_set_pmu_events(mask, attr); 681 694 ··· 684 697 armv8pmu_enable_counter(mask); 685 698 } 686 699 687 - static void armv8pmu_disable_counter(u32 mask) 700 + static void armv8pmu_disable_counter(u64 mask) 688 701 { 689 702 write_pmcntenclr(mask); 690 703 /* ··· 697 710 static void armv8pmu_disable_event_counter(struct perf_event *event) 698 711 { 699 712 struct perf_event_attr *attr = &event->attr; 700 - u32 mask = armv8pmu_event_cnten_mask(event); 713 + u64 mask = armv8pmu_event_cnten_mask(event); 701 714 702 715 kvm_clr_pmu_events(mask); 703 716 ··· 706 719 armv8pmu_disable_counter(mask); 707 720 } 708 721 709 - static void armv8pmu_enable_intens(u32 mask) 722 + static void armv8pmu_enable_intens(u64 mask) 710 723 { 711 724 write_pmintenset(mask); 712 725 } 713 726 714 727 static void armv8pmu_enable_event_irq(struct perf_event *event) 715 728 { 716 - u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); 717 - armv8pmu_enable_intens(BIT(counter)); 729 + armv8pmu_enable_intens(BIT(event->hw.idx)); 718 730 } 719 731 720 - static void armv8pmu_disable_intens(u32 mask) 732 + static void armv8pmu_disable_intens(u64 mask) 721 733 { 722 734 write_pmintenclr(mask); 723 735 isb(); ··· 727 741 728 742 static void armv8pmu_disable_event_irq(struct perf_event *event) 729 743 { 730 - u32 counter = ARMV8_IDX_TO_COUNTER(event->hw.idx); 731 - armv8pmu_disable_intens(BIT(counter)); 744 + armv8pmu_disable_intens(BIT(event->hw.idx)); 732 745 } 733 746 734 - static u32 armv8pmu_getreset_flags(void) 747 + static u64 armv8pmu_getreset_flags(void) 735 748 { 736 - u32 value; 749 + u64 value; 737 750 738 751 /* Read */ 739 752 value = read_pmovsclr(); ··· 771 786 struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events); 772 787 773 788 /* Clear any unused counters to avoid leaking their contents */ 774 - for_each_clear_bit(i, cpuc->used_mask, cpu_pmu->num_events) { 775 - if (i == ARMV8_IDX_CYCLE_COUNTER) 789 + for_each_andnot_bit(i, cpu_pmu->cntr_mask, cpuc->used_mask, 790 + ARMPMU_MAX_HWEVENTS) { 791 + if (i == ARMV8_PMU_CYCLE_IDX) 776 792 write_pmccntr(0); 793 + else if (i == ARMV8_PMU_INSTR_IDX) 794 + write_pmicntr(0); 777 795 else 778 796 armv8pmu_write_evcntr(i, 0); 779 797 } ··· 830 842 831 843 static irqreturn_t armv8pmu_handle_irq(struct arm_pmu *cpu_pmu) 832 844 { 833 - u32 pmovsr; 845 + u64 pmovsr; 834 846 struct perf_sample_data data; 835 847 struct pmu_hw_events *cpuc = this_cpu_ptr(cpu_pmu->hw_events); 836 848 struct pt_regs *regs; ··· 857 869 * to prevent skews in group events. 858 870 */ 859 871 armv8pmu_stop(cpu_pmu); 860 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 872 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 861 873 struct perf_event *event = cpuc->events[idx]; 862 874 struct hw_perf_event *hwc; 863 875 ··· 896 908 { 897 909 int idx; 898 910 899 - for (idx = ARMV8_IDX_COUNTER0; idx < cpu_pmu->num_events; idx++) { 911 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS) { 900 912 if (!test_and_set_bit(idx, cpuc->used_mask)) 901 913 return idx; 902 914 } ··· 912 924 * Chaining requires two consecutive event counters, where 913 925 * the lower idx must be even. 914 926 */ 915 - for (idx = ARMV8_IDX_COUNTER0 + 1; idx < cpu_pmu->num_events; idx += 2) { 927 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV8_PMU_MAX_GENERAL_COUNTERS) { 928 + if (!(idx & 0x1)) 929 + continue; 916 930 if (!test_and_set_bit(idx, cpuc->used_mask)) { 917 931 /* Check if the preceding even counter is available */ 918 932 if (!test_and_set_bit(idx - 1, cpuc->used_mask)) ··· 936 946 /* Always prefer to place a cycle counter into the cycle counter. */ 937 947 if ((evtype == ARMV8_PMUV3_PERFCTR_CPU_CYCLES) && 938 948 !armv8pmu_event_get_threshold(&event->attr)) { 939 - if (!test_and_set_bit(ARMV8_IDX_CYCLE_COUNTER, cpuc->used_mask)) 940 - return ARMV8_IDX_CYCLE_COUNTER; 949 + if (!test_and_set_bit(ARMV8_PMU_CYCLE_IDX, cpuc->used_mask)) 950 + return ARMV8_PMU_CYCLE_IDX; 941 951 else if (armv8pmu_event_is_64bit(event) && 942 952 armv8pmu_event_want_user_access(event) && 943 953 !armv8pmu_has_long_event(cpu_pmu)) 944 954 return -EAGAIN; 955 + } 956 + 957 + /* 958 + * Always prefer to place a instruction counter into the instruction counter, 959 + * but don't expose the instruction counter to userspace access as userspace 960 + * may not know how to handle it. 961 + */ 962 + if ((evtype == ARMV8_PMUV3_PERFCTR_INST_RETIRED) && 963 + !armv8pmu_event_get_threshold(&event->attr) && 964 + test_bit(ARMV8_PMU_INSTR_IDX, cpu_pmu->cntr_mask) && 965 + !armv8pmu_event_want_user_access(event)) { 966 + if (!test_and_set_bit(ARMV8_PMU_INSTR_IDX, cpuc->used_mask)) 967 + return ARMV8_PMU_INSTR_IDX; 945 968 } 946 969 947 970 /* ··· 981 978 if (!sysctl_perf_user_access || !armv8pmu_event_has_user_read(event)) 982 979 return 0; 983 980 984 - /* 985 - * We remap the cycle counter index to 32 to 986 - * match the offset applied to the rest of 987 - * the counter indices. 988 - */ 989 - if (event->hw.idx == ARMV8_IDX_CYCLE_COUNTER) 990 - return ARMV8_IDX_CYCLE_COUNTER_USER; 991 - 992 - return event->hw.idx; 981 + return event->hw.idx + 1; 993 982 } 994 983 995 984 /* ··· 1056 1061 static void armv8pmu_reset(void *info) 1057 1062 { 1058 1063 struct arm_pmu *cpu_pmu = (struct arm_pmu *)info; 1059 - u64 pmcr; 1064 + u64 pmcr, mask; 1065 + 1066 + bitmap_to_arr64(&mask, cpu_pmu->cntr_mask, ARMPMU_MAX_HWEVENTS); 1060 1067 1061 1068 /* The counter and interrupt enable registers are unknown at reset. */ 1062 - armv8pmu_disable_counter(U32_MAX); 1063 - armv8pmu_disable_intens(U32_MAX); 1069 + armv8pmu_disable_counter(mask); 1070 + armv8pmu_disable_intens(mask); 1064 1071 1065 1072 /* Clear the counters we flip at guest entry/exit */ 1066 - kvm_clr_pmu_events(U32_MAX); 1073 + kvm_clr_pmu_events(mask); 1067 1074 1068 1075 /* 1069 1076 * Initialize & Reset PMNC. Request overflow interrupt for ··· 1086 1089 if (event->attr.type == PERF_TYPE_HARDWARE && 1087 1090 event->attr.config == PERF_COUNT_HW_BRANCH_INSTRUCTIONS) { 1088 1091 1089 - if (test_bit(ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED, 1090 - armpmu->pmceid_bitmap)) 1091 - return ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED; 1092 - 1093 1092 if (test_bit(ARMV8_PMUV3_PERFCTR_BR_RETIRED, 1094 1093 armpmu->pmceid_bitmap)) 1095 1094 return ARMV8_PMUV3_PERFCTR_BR_RETIRED; 1095 + 1096 + if (test_bit(ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED, 1097 + armpmu->pmceid_bitmap)) 1098 + return ARMV8_PMUV3_PERFCTR_PC_WRITE_RETIRED; 1096 1099 1097 1100 return HW_OP_UNSUPPORTED; 1098 1101 } ··· 1208 1211 probe->present = true; 1209 1212 1210 1213 /* Read the nb of CNTx counters supported from PMNC */ 1211 - cpu_pmu->num_events = FIELD_GET(ARMV8_PMU_PMCR_N, armv8pmu_pmcr_read()); 1214 + bitmap_set(cpu_pmu->cntr_mask, 1215 + 0, FIELD_GET(ARMV8_PMU_PMCR_N, armv8pmu_pmcr_read())); 1212 1216 1213 1217 /* Add the CPU cycles counter */ 1214 - cpu_pmu->num_events += 1; 1218 + set_bit(ARMV8_PMU_CYCLE_IDX, cpu_pmu->cntr_mask); 1219 + 1220 + /* Add the CPU instructions counter */ 1221 + if (pmuv3_has_icntr()) 1222 + set_bit(ARMV8_PMU_INSTR_IDX, cpu_pmu->cntr_mask); 1215 1223 1216 1224 pmceid[0] = pmceid_raw[0] = read_pmceid0(); 1217 1225 pmceid[1] = pmceid_raw[1] = read_pmceid1();
+4 -5
drivers/perf/arm_spe_pmu.c
··· 41 41 42 42 /* 43 43 * Cache if the event is allowed to trace Context information. 44 - * This allows us to perform the check, i.e, perfmon_capable(), 44 + * This allows us to perform the check, i.e, perf_allow_kernel(), 45 45 * in the context of the event owner, once, during the event_init(). 46 46 */ 47 47 #define SPE_PMU_HW_FLAGS_CX 0x00001 ··· 50 50 51 51 static void set_spe_event_has_cx(struct perf_event *event) 52 52 { 53 - if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && perfmon_capable()) 53 + if (IS_ENABLED(CONFIG_PID_IN_CONTEXTIDR) && !perf_allow_kernel(&event->attr)) 54 54 event->hw.flags |= SPE_PMU_HW_FLAGS_CX; 55 55 } 56 56 ··· 745 745 746 746 set_spe_event_has_cx(event); 747 747 reg = arm_spe_event_to_pmscr(event); 748 - if (!perfmon_capable() && 749 - (reg & (PMSCR_EL1_PA | PMSCR_EL1_PCT))) 750 - return -EACCES; 748 + if (reg & (PMSCR_EL1_PA | PMSCR_EL1_PCT)) 749 + return perf_allow_kernel(&event->attr); 751 750 752 751 return 0; 753 752 }
+4 -2
drivers/perf/arm_v6_pmu.c
··· 64 64 ARMV6_CYCLE_COUNTER = 0, 65 65 ARMV6_COUNTER0, 66 66 ARMV6_COUNTER1, 67 + ARMV6_NUM_COUNTERS 67 68 }; 68 69 69 70 /* ··· 255 254 */ 256 255 armv6_pmcr_write(pmcr); 257 256 258 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 257 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV6_NUM_COUNTERS) { 259 258 struct perf_event *event = cpuc->events[idx]; 260 259 struct hw_perf_event *hwc; 261 260 ··· 392 391 cpu_pmu->start = armv6pmu_start; 393 392 cpu_pmu->stop = armv6pmu_stop; 394 393 cpu_pmu->map_event = armv6_map_event; 395 - cpu_pmu->num_events = 3; 394 + 395 + bitmap_set(cpu_pmu->cntr_mask, 0, ARMV6_NUM_COUNTERS); 396 396 } 397 397 398 398 static int armv6_1136_pmu_init(struct arm_pmu *cpu_pmu)
+29 -48
drivers/perf/arm_v7_pmu.c
··· 649 649 /* 650 650 * Perf Events' indices 651 651 */ 652 - #define ARMV7_IDX_CYCLE_COUNTER 0 653 - #define ARMV7_IDX_COUNTER0 1 654 - #define ARMV7_IDX_COUNTER_LAST(cpu_pmu) \ 655 - (ARMV7_IDX_CYCLE_COUNTER + cpu_pmu->num_events - 1) 656 - 657 - #define ARMV7_MAX_COUNTERS 32 658 - #define ARMV7_COUNTER_MASK (ARMV7_MAX_COUNTERS - 1) 659 - 652 + #define ARMV7_IDX_CYCLE_COUNTER 31 653 + #define ARMV7_IDX_COUNTER_MAX 31 660 654 /* 661 655 * ARMv7 low level PMNC access 662 656 */ 663 - 664 - /* 665 - * Perf Event to low level counters mapping 666 - */ 667 - #define ARMV7_IDX_TO_COUNTER(x) \ 668 - (((x) - ARMV7_IDX_COUNTER0) & ARMV7_COUNTER_MASK) 669 657 670 658 /* 671 659 * Per-CPU PMNC: config reg ··· 713 725 714 726 static inline int armv7_pmnc_counter_valid(struct arm_pmu *cpu_pmu, int idx) 715 727 { 716 - return idx >= ARMV7_IDX_CYCLE_COUNTER && 717 - idx <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); 728 + return test_bit(idx, cpu_pmu->cntr_mask); 718 729 } 719 730 720 731 static inline int armv7_pmnc_counter_has_overflowed(u32 pmnc, int idx) 721 732 { 722 - return pmnc & BIT(ARMV7_IDX_TO_COUNTER(idx)); 733 + return pmnc & BIT(idx); 723 734 } 724 735 725 736 static inline void armv7_pmnc_select_counter(int idx) 726 737 { 727 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 728 - asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (counter)); 738 + asm volatile("mcr p15, 0, %0, c9, c12, 5" : : "r" (idx)); 729 739 isb(); 730 740 } 731 741 ··· 773 787 774 788 static inline void armv7_pmnc_enable_counter(int idx) 775 789 { 776 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 777 - asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(counter))); 790 + asm volatile("mcr p15, 0, %0, c9, c12, 1" : : "r" (BIT(idx))); 778 791 } 779 792 780 793 static inline void armv7_pmnc_disable_counter(int idx) 781 794 { 782 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 783 - asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(counter))); 795 + asm volatile("mcr p15, 0, %0, c9, c12, 2" : : "r" (BIT(idx))); 784 796 } 785 797 786 798 static inline void armv7_pmnc_enable_intens(int idx) 787 799 { 788 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 789 - asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(counter))); 800 + asm volatile("mcr p15, 0, %0, c9, c14, 1" : : "r" (BIT(idx))); 790 801 } 791 802 792 803 static inline void armv7_pmnc_disable_intens(int idx) 793 804 { 794 - u32 counter = ARMV7_IDX_TO_COUNTER(idx); 795 - asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(counter))); 805 + asm volatile("mcr p15, 0, %0, c9, c14, 2" : : "r" (BIT(idx))); 796 806 isb(); 797 807 /* Clear the overflow flag in case an interrupt is pending. */ 798 - asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(counter))); 808 + asm volatile("mcr p15, 0, %0, c9, c12, 3" : : "r" (BIT(idx))); 799 809 isb(); 800 810 } 801 811 ··· 835 853 asm volatile("mrc p15, 0, %0, c9, c13, 0" : "=r" (val)); 836 854 pr_info("CCNT =0x%08x\n", val); 837 855 838 - for (cnt = ARMV7_IDX_COUNTER0; 839 - cnt <= ARMV7_IDX_COUNTER_LAST(cpu_pmu); cnt++) { 856 + for_each_set_bit(cnt, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 840 857 armv7_pmnc_select_counter(cnt); 841 858 asm volatile("mrc p15, 0, %0, c9, c13, 2" : "=r" (val)); 842 - pr_info("CNT[%d] count =0x%08x\n", 843 - ARMV7_IDX_TO_COUNTER(cnt), val); 859 + pr_info("CNT[%d] count =0x%08x\n", cnt, val); 844 860 asm volatile("mrc p15, 0, %0, c9, c13, 1" : "=r" (val)); 845 - pr_info("CNT[%d] evtsel=0x%08x\n", 846 - ARMV7_IDX_TO_COUNTER(cnt), val); 861 + pr_info("CNT[%d] evtsel=0x%08x\n", cnt, val); 847 862 } 848 863 } 849 864 #endif ··· 937 958 */ 938 959 regs = get_irq_regs(); 939 960 940 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 961 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 941 962 struct perf_event *event = cpuc->events[idx]; 942 963 struct hw_perf_event *hwc; 943 964 ··· 1006 1027 * For anything other than a cycle counter, try and use 1007 1028 * the events counters 1008 1029 */ 1009 - for (idx = ARMV7_IDX_COUNTER0; idx < cpu_pmu->num_events; ++idx) { 1030 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 1010 1031 if (!test_and_set_bit(idx, cpuc->used_mask)) 1011 1032 return idx; 1012 1033 } ··· 1052 1073 static void armv7pmu_reset(void *info) 1053 1074 { 1054 1075 struct arm_pmu *cpu_pmu = (struct arm_pmu *)info; 1055 - u32 idx, nb_cnt = cpu_pmu->num_events, val; 1076 + u32 idx, val; 1056 1077 1057 1078 if (cpu_pmu->secure_access) { 1058 1079 asm volatile("mrc p15, 0, %0, c1, c1, 1" : "=r" (val)); ··· 1061 1082 } 1062 1083 1063 1084 /* The counter and interrupt enable registers are unknown at reset. */ 1064 - for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { 1085 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMPMU_MAX_HWEVENTS) { 1065 1086 armv7_pmnc_disable_counter(idx); 1066 1087 armv7_pmnc_disable_intens(idx); 1067 1088 } ··· 1140 1161 1141 1162 static void armv7_read_num_pmnc_events(void *info) 1142 1163 { 1143 - int *nb_cnt = info; 1164 + int nb_cnt; 1165 + struct arm_pmu *cpu_pmu = info; 1144 1166 1145 1167 /* Read the nb of CNTx counters supported from PMNC */ 1146 - *nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; 1168 + nb_cnt = (armv7_pmnc_read() >> ARMV7_PMNC_N_SHIFT) & ARMV7_PMNC_N_MASK; 1169 + bitmap_set(cpu_pmu->cntr_mask, 0, nb_cnt); 1147 1170 1148 1171 /* Add the CPU cycles counter */ 1149 - *nb_cnt += 1; 1172 + set_bit(ARMV7_IDX_CYCLE_COUNTER, cpu_pmu->cntr_mask); 1150 1173 } 1151 1174 1152 1175 static int armv7_probe_num_events(struct arm_pmu *arm_pmu) 1153 1176 { 1154 1177 return smp_call_function_any(&arm_pmu->supported_cpus, 1155 1178 armv7_read_num_pmnc_events, 1156 - &arm_pmu->num_events, 1); 1179 + arm_pmu, 1); 1157 1180 } 1158 1181 1159 1182 static int armv7_a8_pmu_init(struct arm_pmu *cpu_pmu) ··· 1505 1524 { 1506 1525 u32 vval, fval; 1507 1526 struct arm_pmu *cpu_pmu = info; 1508 - u32 idx, nb_cnt = cpu_pmu->num_events; 1527 + u32 idx; 1509 1528 1510 1529 armv7pmu_reset(info); 1511 1530 ··· 1519 1538 venum_post_pmresr(vval, fval); 1520 1539 1521 1540 /* Reset PMxEVNCTCR to sane default */ 1522 - for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { 1541 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 1523 1542 armv7_pmnc_select_counter(idx); 1524 1543 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0)); 1525 1544 } ··· 1543 1562 * Lower bits are reserved for use by the counters (see 1544 1563 * armv7pmu_get_event_idx() for more info) 1545 1564 */ 1546 - bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1; 1565 + bit += bitmap_weight(cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX); 1547 1566 1548 1567 return bit; 1549 1568 } ··· 1826 1845 { 1827 1846 u32 vval, fval; 1828 1847 struct arm_pmu *cpu_pmu = info; 1829 - u32 idx, nb_cnt = cpu_pmu->num_events; 1848 + u32 idx; 1830 1849 1831 1850 armv7pmu_reset(info); 1832 1851 ··· 1841 1860 venum_post_pmresr(vval, fval); 1842 1861 1843 1862 /* Reset PMxEVNCTCR to sane default */ 1844 - for (idx = ARMV7_IDX_CYCLE_COUNTER; idx < nb_cnt; ++idx) { 1863 + for_each_set_bit(idx, cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX) { 1845 1864 armv7_pmnc_select_counter(idx); 1846 1865 asm volatile("mcr p15, 0, %0, c9, c15, 0" : : "r" (0)); 1847 1866 } ··· 1864 1883 * Lower bits are reserved for use by the counters (see 1865 1884 * armv7pmu_get_event_idx() for more info) 1866 1885 */ 1867 - bit += ARMV7_IDX_COUNTER_LAST(cpu_pmu) + 1; 1886 + bit += bitmap_weight(cpu_pmu->cntr_mask, ARMV7_IDX_COUNTER_MAX); 1868 1887 1869 1888 return bit; 1870 1889 }
+8 -4
drivers/perf/arm_xscale_pmu.c
··· 53 53 XSCALE_COUNTER2, 54 54 XSCALE_COUNTER3, 55 55 }; 56 + #define XSCALE1_NUM_COUNTERS 3 57 + #define XSCALE2_NUM_COUNTERS 5 56 58 57 59 static const unsigned xscale_perf_map[PERF_COUNT_HW_MAX] = { 58 60 PERF_MAP_ALL_UNSUPPORTED, ··· 170 168 171 169 regs = get_irq_regs(); 172 170 173 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 171 + for_each_set_bit(idx, cpu_pmu->cntr_mask, XSCALE1_NUM_COUNTERS) { 174 172 struct perf_event *event = cpuc->events[idx]; 175 173 struct hw_perf_event *hwc; 176 174 ··· 366 364 cpu_pmu->start = xscale1pmu_start; 367 365 cpu_pmu->stop = xscale1pmu_stop; 368 366 cpu_pmu->map_event = xscale_map_event; 369 - cpu_pmu->num_events = 3; 367 + 368 + bitmap_set(cpu_pmu->cntr_mask, 0, XSCALE1_NUM_COUNTERS); 370 369 371 370 return 0; 372 371 } ··· 503 500 504 501 regs = get_irq_regs(); 505 502 506 - for (idx = 0; idx < cpu_pmu->num_events; ++idx) { 503 + for_each_set_bit(idx, cpu_pmu->cntr_mask, XSCALE2_NUM_COUNTERS) { 507 504 struct perf_event *event = cpuc->events[idx]; 508 505 struct hw_perf_event *hwc; 509 506 ··· 722 719 cpu_pmu->start = xscale2pmu_start; 723 720 cpu_pmu->stop = xscale2pmu_stop; 724 721 cpu_pmu->map_event = xscale_map_event; 725 - cpu_pmu->num_events = 5; 722 + 723 + bitmap_set(cpu_pmu->cntr_mask, 0, XSCALE2_NUM_COUNTERS); 726 724 727 725 return 0; 728 726 }
+9 -13
drivers/perf/dwc_pcie_pmu.c
··· 107 107 108 108 static const struct dwc_pcie_vendor_id dwc_pcie_vendor_ids[] = { 109 109 {.vendor_id = PCI_VENDOR_ID_ALIBABA }, 110 + {.vendor_id = PCI_VENDOR_ID_QCOM }, 110 111 {} /* terminator */ 111 112 }; 112 113 ··· 557 556 { 558 557 struct platform_device *plat_dev; 559 558 struct dwc_pcie_dev_info *dev_info; 560 - u32 bdf; 559 + u32 sbdf; 561 560 562 - bdf = PCI_DEVID(pdev->bus->number, pdev->devfn); 563 - plat_dev = platform_device_register_data(NULL, "dwc_pcie_pmu", bdf, 561 + sbdf = (pci_domain_nr(pdev->bus) << 16) | PCI_DEVID(pdev->bus->number, pdev->devfn); 562 + plat_dev = platform_device_register_data(NULL, "dwc_pcie_pmu", sbdf, 564 563 pdev, sizeof(*pdev)); 565 564 566 565 if (IS_ERR(plat_dev)) ··· 612 611 struct pci_dev *pdev = plat_dev->dev.platform_data; 613 612 struct dwc_pcie_pmu *pcie_pmu; 614 613 char *name; 615 - u32 bdf, val; 614 + u32 sbdf, val; 616 615 u16 vsec; 617 616 int ret; 618 617 619 618 vsec = pci_find_vsec_capability(pdev, pdev->vendor, 620 619 DWC_PCIE_VSEC_RAS_DES_ID); 621 620 pci_read_config_dword(pdev, vsec + PCI_VNDR_HEADER, &val); 622 - bdf = PCI_DEVID(pdev->bus->number, pdev->devfn); 623 - name = devm_kasprintf(&plat_dev->dev, GFP_KERNEL, "dwc_rootport_%x", bdf); 621 + sbdf = plat_dev->id; 622 + name = devm_kasprintf(&plat_dev->dev, GFP_KERNEL, "dwc_rootport_%x", sbdf); 624 623 if (!name) 625 624 return -ENOMEM; 626 625 ··· 651 650 ret = cpuhp_state_add_instance(dwc_pcie_pmu_hp_state, 652 651 &pcie_pmu->cpuhp_node); 653 652 if (ret) { 654 - pci_err(pdev, "Error %d registering hotplug @%x\n", ret, bdf); 653 + pci_err(pdev, "Error %d registering hotplug @%x\n", ret, sbdf); 655 654 return ret; 656 655 } 657 656 ··· 664 663 665 664 ret = perf_pmu_register(&pcie_pmu->pmu, name, -1); 666 665 if (ret) { 667 - pci_err(pdev, "Error %d registering PMU @%x\n", ret, bdf); 666 + pci_err(pdev, "Error %d registering PMU @%x\n", ret, sbdf); 668 667 return ret; 669 668 } 670 669 ret = devm_add_action_or_reset(&plat_dev->dev, dwc_pcie_unregister_pmu, ··· 727 726 static int __init dwc_pcie_pmu_init(void) 728 727 { 729 728 struct pci_dev *pdev = NULL; 730 - bool found = false; 731 729 int ret; 732 730 733 731 for_each_pci_dev(pdev) { ··· 738 738 pci_dev_put(pdev); 739 739 return ret; 740 740 } 741 - 742 - found = true; 743 741 } 744 - if (!found) 745 - return -ENODEV; 746 742 747 743 ret = cpuhp_setup_state_multi(CPUHP_AP_ONLINE_DYN, 748 744 "perf/dwc_pcie_pmu:online",
+33 -1
drivers/perf/hisilicon/hisi_pcie_pmu.c
··· 141 141 } 142 142 static DEVICE_ATTR_RO(bus); 143 143 144 + static ssize_t bdf_min_show(struct device *dev, struct device_attribute *attr, char *buf) 145 + { 146 + struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev)); 147 + 148 + return sysfs_emit(buf, "%#04x\n", pcie_pmu->bdf_min); 149 + } 150 + static DEVICE_ATTR_RO(bdf_min); 151 + 152 + static ssize_t bdf_max_show(struct device *dev, struct device_attribute *attr, char *buf) 153 + { 154 + struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(dev_get_drvdata(dev)); 155 + 156 + return sysfs_emit(buf, "%#04x\n", pcie_pmu->bdf_max); 157 + } 158 + static DEVICE_ATTR_RO(bdf_max); 159 + 144 160 static struct hisi_pcie_reg_pair 145 161 hisi_pcie_parse_reg_value(struct hisi_pcie_pmu *pcie_pmu, u32 reg_off) 146 162 { ··· 224 208 static u64 hisi_pcie_pmu_get_event_ctrl_val(struct perf_event *event) 225 209 { 226 210 u64 port, trig_len, thr_len, len_mode; 227 - u64 reg = HISI_PCIE_INIT_SET; 211 + u64 reg = 0; 228 212 229 213 /* Config HISI_PCIE_EVENT_CTRL according to event. */ 230 214 reg |= FIELD_PREP(HISI_PCIE_EVENT_M, hisi_pcie_get_real_event(event)); ··· 468 452 struct hisi_pcie_pmu *pcie_pmu = to_pcie_pmu(event->pmu); 469 453 struct hw_perf_event *hwc = &event->hw; 470 454 int idx = hwc->idx; 455 + u64 orig_cnt, cnt; 456 + 457 + orig_cnt = hisi_pcie_pmu_read_counter(event); 471 458 472 459 local64_set(&hwc->prev_count, HISI_PCIE_INIT_VAL); 473 460 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_CNT, idx, HISI_PCIE_INIT_VAL); 474 461 hisi_pcie_pmu_writeq(pcie_pmu, HISI_PCIE_EXT_CNT, idx, HISI_PCIE_INIT_VAL); 462 + 463 + /* 464 + * The counter maybe unwritable if the target event is unsupported. 465 + * Check this by comparing the counts after setting the period. If 466 + * the counts stay unchanged after setting the period then update 467 + * the hwc->prev_count correctly. Otherwise the final counts user 468 + * get maybe totally wrong. 469 + */ 470 + cnt = hisi_pcie_pmu_read_counter(event); 471 + if (orig_cnt == cnt) 472 + local64_set(&hwc->prev_count, cnt); 475 473 } 476 474 477 475 static void hisi_pcie_pmu_enable_counter(struct hisi_pcie_pmu *pcie_pmu, struct hw_perf_event *hwc) ··· 779 749 780 750 static struct attribute *hisi_pcie_pmu_bus_attrs[] = { 781 751 &dev_attr_bus.attr, 752 + &dev_attr_bdf_max.attr, 753 + &dev_attr_bdf_min.attr, 782 754 NULL 783 755 }; 784 756
+2
drivers/virt/coco/Kconfig
··· 9 9 10 10 source "drivers/virt/coco/efi_secret/Kconfig" 11 11 12 + source "drivers/virt/coco/pkvm-guest/Kconfig" 13 + 12 14 source "drivers/virt/coco/sev-guest/Kconfig" 13 15 14 16 source "drivers/virt/coco/tdx-guest/Kconfig"
+1
drivers/virt/coco/Makefile
··· 4 4 # 5 5 obj-$(CONFIG_TSM_REPORTS) += tsm.o 6 6 obj-$(CONFIG_EFI_SECRET) += efi_secret/ 7 + obj-$(CONFIG_ARM_PKVM_GUEST) += pkvm-guest/ 7 8 obj-$(CONFIG_SEV_GUEST) += sev-guest/ 8 9 obj-$(CONFIG_INTEL_TDX_GUEST) += tdx-guest/
+10
drivers/virt/coco/pkvm-guest/Kconfig
··· 1 + config ARM_PKVM_GUEST 2 + bool "Arm pKVM protected guest driver" 3 + depends on ARM64 4 + help 5 + Protected guests running under the pKVM hypervisor on arm64 6 + are isolated from the host and must issue hypercalls to enable 7 + interaction with virtual devices. This driver implements 8 + support for probing and issuing these hypercalls. 9 + 10 + If unsure, say 'N'.
+2
drivers/virt/coco/pkvm-guest/Makefile
··· 1 + # SPDX-License-Identifier: GPL-2.0-only 2 + obj-$(CONFIG_ARM_PKVM_GUEST) += arm-pkvm-guest.o
+127
drivers/virt/coco/pkvm-guest/arm-pkvm-guest.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-only 2 + /* 3 + * Support for the hypercall interface exposed to protected guests by 4 + * pKVM. 5 + * 6 + * Author: Will Deacon <will@kernel.org> 7 + * Copyright (C) 2024 Google LLC 8 + */ 9 + 10 + #include <linux/arm-smccc.h> 11 + #include <linux/array_size.h> 12 + #include <linux/io.h> 13 + #include <linux/mem_encrypt.h> 14 + #include <linux/mm.h> 15 + #include <linux/pgtable.h> 16 + 17 + #include <asm/hypervisor.h> 18 + 19 + static size_t pkvm_granule; 20 + 21 + static int arm_smccc_do_one_page(u32 func_id, phys_addr_t phys) 22 + { 23 + phys_addr_t end = phys + PAGE_SIZE; 24 + 25 + while (phys < end) { 26 + struct arm_smccc_res res; 27 + 28 + arm_smccc_1_1_invoke(func_id, phys, 0, 0, &res); 29 + if (res.a0 != SMCCC_RET_SUCCESS) 30 + return -EPERM; 31 + 32 + phys += pkvm_granule; 33 + } 34 + 35 + return 0; 36 + } 37 + 38 + static int __set_memory_range(u32 func_id, unsigned long start, int numpages) 39 + { 40 + void *addr = (void *)start, *end = addr + numpages * PAGE_SIZE; 41 + 42 + while (addr < end) { 43 + int err; 44 + 45 + err = arm_smccc_do_one_page(func_id, virt_to_phys(addr)); 46 + if (err) 47 + return err; 48 + 49 + addr += PAGE_SIZE; 50 + } 51 + 52 + return 0; 53 + } 54 + 55 + static int pkvm_set_memory_encrypted(unsigned long addr, int numpages) 56 + { 57 + return __set_memory_range(ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID, 58 + addr, numpages); 59 + } 60 + 61 + static int pkvm_set_memory_decrypted(unsigned long addr, int numpages) 62 + { 63 + return __set_memory_range(ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID, 64 + addr, numpages); 65 + } 66 + 67 + static const struct arm64_mem_crypt_ops pkvm_crypt_ops = { 68 + .encrypt = pkvm_set_memory_encrypted, 69 + .decrypt = pkvm_set_memory_decrypted, 70 + }; 71 + 72 + static int mmio_guard_ioremap_hook(phys_addr_t phys, size_t size, 73 + pgprot_t *prot) 74 + { 75 + phys_addr_t end; 76 + pteval_t protval = pgprot_val(*prot); 77 + 78 + /* 79 + * We only expect MMIO emulation for regions mapped with device 80 + * attributes. 81 + */ 82 + if (protval != PROT_DEVICE_nGnRE && protval != PROT_DEVICE_nGnRnE) 83 + return 0; 84 + 85 + phys = PAGE_ALIGN_DOWN(phys); 86 + end = phys + PAGE_ALIGN(size); 87 + 88 + while (phys < end) { 89 + const int func_id = ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID; 90 + int err; 91 + 92 + err = arm_smccc_do_one_page(func_id, phys); 93 + if (err) 94 + return err; 95 + 96 + phys += PAGE_SIZE; 97 + } 98 + 99 + return 0; 100 + } 101 + 102 + void pkvm_init_hyp_services(void) 103 + { 104 + int i; 105 + struct arm_smccc_res res; 106 + const u32 funcs[] = { 107 + ARM_SMCCC_KVM_FUNC_HYP_MEMINFO, 108 + ARM_SMCCC_KVM_FUNC_MEM_SHARE, 109 + ARM_SMCCC_KVM_FUNC_MEM_UNSHARE, 110 + }; 111 + 112 + for (i = 0; i < ARRAY_SIZE(funcs); ++i) { 113 + if (!kvm_arm_hyp_service_available(funcs[i])) 114 + return; 115 + } 116 + 117 + arm_smccc_1_1_invoke(ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID, 118 + 0, 0, 0, &res); 119 + if (res.a0 > PAGE_SIZE) /* Includes error codes */ 120 + return; 121 + 122 + pkvm_granule = res.a0; 123 + arm64_mem_crypt_ops_register(&pkvm_crypt_ops); 124 + 125 + if (kvm_arm_hyp_service_available(ARM_SMCCC_KVM_FUNC_MMIO_GUARD)) 126 + arm64_ioremap_prot_hook_register(&mmio_guard_ioremap_hook); 127 + }
+2
fs/proc/task_mmu.c
··· 976 976 [ilog2(VM_PKEY_BIT0)] = "", 977 977 [ilog2(VM_PKEY_BIT1)] = "", 978 978 [ilog2(VM_PKEY_BIT2)] = "", 979 + #if VM_PKEY_BIT3 979 980 [ilog2(VM_PKEY_BIT3)] = "", 981 + #endif 980 982 #if VM_PKEY_BIT4 981 983 [ilog2(VM_PKEY_BIT4)] = "", 982 984 #endif
+4 -4
include/kvm/arm_pmu.h
··· 10 10 #include <linux/perf_event.h> 11 11 #include <linux/perf/arm_pmuv3.h> 12 12 13 - #define ARMV8_PMU_CYCLE_IDX (ARMV8_PMU_MAX_COUNTERS - 1) 13 + #define KVM_ARMV8_PMU_MAX_COUNTERS 32 14 14 15 15 #if IS_ENABLED(CONFIG_HW_PERF_EVENTS) && IS_ENABLED(CONFIG_KVM) 16 16 struct kvm_pmc { ··· 19 19 }; 20 20 21 21 struct kvm_pmu_events { 22 - u32 events_host; 23 - u32 events_guest; 22 + u64 events_host; 23 + u64 events_guest; 24 24 }; 25 25 26 26 struct kvm_pmu { 27 27 struct irq_work overflow_work; 28 28 struct kvm_pmu_events events; 29 - struct kvm_pmc pmc[ARMV8_PMU_MAX_COUNTERS]; 29 + struct kvm_pmc pmc[KVM_ARMV8_PMU_MAX_COUNTERS]; 30 30 int irq_num; 31 31 bool created; 32 32 bool irq_level;
+88
include/linux/arm-smccc.h
··· 115 115 /* KVM "vendor specific" services */ 116 116 #define ARM_SMCCC_KVM_FUNC_FEATURES 0 117 117 #define ARM_SMCCC_KVM_FUNC_PTP 1 118 + /* Start of pKVM hypercall range */ 119 + #define ARM_SMCCC_KVM_FUNC_HYP_MEMINFO 2 120 + #define ARM_SMCCC_KVM_FUNC_MEM_SHARE 3 121 + #define ARM_SMCCC_KVM_FUNC_MEM_UNSHARE 4 122 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_5 5 123 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_6 6 124 + #define ARM_SMCCC_KVM_FUNC_MMIO_GUARD 7 125 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_8 8 126 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_9 9 127 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_10 10 128 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_11 11 129 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_12 12 130 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_13 13 131 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_14 14 132 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_15 15 133 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_16 16 134 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_17 17 135 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_18 18 136 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_19 19 137 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_20 20 138 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_21 21 139 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_22 22 140 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_23 23 141 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_24 24 142 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_25 25 143 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_26 26 144 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_27 27 145 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_28 28 146 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_29 29 147 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_30 30 148 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_31 31 149 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_32 32 150 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_33 33 151 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_34 34 152 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_35 35 153 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_36 36 154 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_37 37 155 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_38 38 156 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_39 39 157 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_40 40 158 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_41 41 159 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_42 42 160 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_43 43 161 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_44 44 162 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_45 45 163 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_46 46 164 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_47 47 165 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_48 48 166 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_49 49 167 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_50 50 168 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_51 51 169 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_52 52 170 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_53 53 171 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_54 54 172 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_55 55 173 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_56 56 174 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_57 57 175 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_58 58 176 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_59 59 177 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_60 60 178 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_61 61 179 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_62 62 180 + #define ARM_SMCCC_KVM_FUNC_PKVM_RESV_63 63 181 + /* End of pKVM hypercall range */ 118 182 #define ARM_SMCCC_KVM_FUNC_FEATURES_2 127 119 183 #define ARM_SMCCC_KVM_NUM_FUNCS 128 120 184 ··· 200 136 ARM_SMCCC_SMC_32, \ 201 137 ARM_SMCCC_OWNER_VENDOR_HYP, \ 202 138 ARM_SMCCC_KVM_FUNC_PTP) 139 + 140 + #define ARM_SMCCC_VENDOR_HYP_KVM_HYP_MEMINFO_FUNC_ID \ 141 + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ 142 + ARM_SMCCC_SMC_64, \ 143 + ARM_SMCCC_OWNER_VENDOR_HYP, \ 144 + ARM_SMCCC_KVM_FUNC_HYP_MEMINFO) 145 + 146 + #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_SHARE_FUNC_ID \ 147 + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ 148 + ARM_SMCCC_SMC_64, \ 149 + ARM_SMCCC_OWNER_VENDOR_HYP, \ 150 + ARM_SMCCC_KVM_FUNC_MEM_SHARE) 151 + 152 + #define ARM_SMCCC_VENDOR_HYP_KVM_MEM_UNSHARE_FUNC_ID \ 153 + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ 154 + ARM_SMCCC_SMC_64, \ 155 + ARM_SMCCC_OWNER_VENDOR_HYP, \ 156 + ARM_SMCCC_KVM_FUNC_MEM_UNSHARE) 157 + 158 + #define ARM_SMCCC_VENDOR_HYP_KVM_MMIO_GUARD_FUNC_ID \ 159 + ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, \ 160 + ARM_SMCCC_SMC_64, \ 161 + ARM_SMCCC_OWNER_VENDOR_HYP, \ 162 + ARM_SMCCC_KVM_FUNC_MMIO_GUARD) 203 163 204 164 /* ptp_kvm counter type ID */ 205 165 #define KVM_PTP_VIRT_COUNTER 0
+12 -8
include/linux/mm.h
··· 334 334 #endif /* CONFIG_ARCH_USES_HIGH_VMA_FLAGS */ 335 335 336 336 #ifdef CONFIG_ARCH_HAS_PKEYS 337 - # define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0 338 - # define VM_PKEY_BIT0 VM_HIGH_ARCH_0 /* A protection key is a 4-bit value */ 339 - # define VM_PKEY_BIT1 VM_HIGH_ARCH_1 /* on x86 and 5-bit value on ppc64 */ 340 - # define VM_PKEY_BIT2 VM_HIGH_ARCH_2 341 - # define VM_PKEY_BIT3 VM_HIGH_ARCH_3 342 - #ifdef CONFIG_PPC 337 + # define VM_PKEY_SHIFT VM_HIGH_ARCH_BIT_0 338 + # define VM_PKEY_BIT0 VM_HIGH_ARCH_0 339 + # define VM_PKEY_BIT1 VM_HIGH_ARCH_1 340 + # define VM_PKEY_BIT2 VM_HIGH_ARCH_2 341 + #if CONFIG_ARCH_PKEY_BITS > 3 342 + # define VM_PKEY_BIT3 VM_HIGH_ARCH_3 343 + #else 344 + # define VM_PKEY_BIT3 0 345 + #endif 346 + #if CONFIG_ARCH_PKEY_BITS > 4 343 347 # define VM_PKEY_BIT4 VM_HIGH_ARCH_4 344 348 #else 345 349 # define VM_PKEY_BIT4 0 ··· 382 378 #endif 383 379 384 380 #if defined(CONFIG_ARM64_MTE) 385 - # define VM_MTE VM_HIGH_ARCH_0 /* Use Tagged memory for access control */ 386 - # define VM_MTE_ALLOWED VM_HIGH_ARCH_1 /* Tagged memory permitted */ 381 + # define VM_MTE VM_HIGH_ARCH_4 /* Use Tagged memory for access control */ 382 + # define VM_MTE_ALLOWED VM_HIGH_ARCH_5 /* Tagged memory permitted */ 387 383 #else 388 384 # define VM_MTE VM_NONE 389 385 # define VM_MTE_ALLOWED VM_NONE
+7 -3
include/linux/perf/arm_pmu.h
··· 17 17 #ifdef CONFIG_ARM_PMU 18 18 19 19 /* 20 - * The ARMv7 CPU PMU supports up to 32 event counters. 20 + * The Armv7 and Armv8.8 or less CPU PMU supports up to 32 event counters. 21 + * The Armv8.9/9.4 CPU PMU supports up to 33 event counters. 21 22 */ 23 + #ifdef CONFIG_ARM 22 24 #define ARMPMU_MAX_HWEVENTS 32 23 - 25 + #else 26 + #define ARMPMU_MAX_HWEVENTS 33 27 + #endif 24 28 /* 25 29 * ARM PMU hw_event flags 26 30 */ ··· 100 96 void (*stop)(struct arm_pmu *); 101 97 void (*reset)(void *); 102 98 int (*map_event)(struct perf_event *event); 103 - int num_events; 99 + DECLARE_BITMAP(cntr_mask, ARMPMU_MAX_HWEVENTS); 104 100 bool secure_access; /* 32-bit ARM only */ 105 101 #define ARMV8_PMUV3_MAX_COMMON_EVENTS 0x40 106 102 DECLARE_BITMAP(pmceid_bitmap, ARMV8_PMUV3_MAX_COMMON_EVENTS);
+6 -3
include/linux/perf/arm_pmuv3.h
··· 6 6 #ifndef __PERF_ARM_PMUV3_H 7 7 #define __PERF_ARM_PMUV3_H 8 8 9 - #define ARMV8_PMU_MAX_COUNTERS 32 10 - #define ARMV8_PMU_COUNTER_MASK (ARMV8_PMU_MAX_COUNTERS - 1) 9 + #define ARMV8_PMU_MAX_GENERAL_COUNTERS 31 10 + #define ARMV8_PMU_CYCLE_IDX 31 11 + #define ARMV8_PMU_INSTR_IDX 32 /* Not accessible from AArch32 */ 11 12 12 13 /* 13 14 * Common architectural and microarchitectural event numbers. ··· 228 227 */ 229 228 #define ARMV8_PMU_OVSR_P GENMASK(30, 0) 230 229 #define ARMV8_PMU_OVSR_C BIT(31) 230 + #define ARMV8_PMU_OVSR_F BIT_ULL(32) /* arm64 only */ 231 231 /* Mask for writable bits is both P and C fields */ 232 - #define ARMV8_PMU_OVERFLOWED_MASK (ARMV8_PMU_OVSR_P | ARMV8_PMU_OVSR_C) 232 + #define ARMV8_PMU_OVERFLOWED_MASK (ARMV8_PMU_OVSR_P | ARMV8_PMU_OVSR_C | \ 233 + ARMV8_PMU_OVSR_F) 233 234 234 235 /* 235 236 * PMXEVTYPER: Event selection reg
+1 -7
include/linux/perf_event.h
··· 1602 1602 return sysctl_perf_event_paranoid > -1; 1603 1603 } 1604 1604 1605 - static inline int perf_allow_kernel(struct perf_event_attr *attr) 1606 - { 1607 - if (sysctl_perf_event_paranoid > 1 && !perfmon_capable()) 1608 - return -EACCES; 1609 - 1610 - return security_perf_event_open(attr, PERF_SECURITY_KERNEL); 1611 - } 1605 + int perf_allow_kernel(struct perf_event_attr *attr); 1612 1606 1613 1607 static inline int perf_allow_cpu(struct perf_event_attr *attr) 1614 1608 {
+1
include/uapi/linux/elf.h
··· 441 441 #define NT_ARM_ZA 0x40c /* ARM SME ZA registers */ 442 442 #define NT_ARM_ZT 0x40d /* ARM SME ZT registers */ 443 443 #define NT_ARM_FPMR 0x40e /* ARM floating point mode register */ 444 + #define NT_ARM_POE 0x40f /* ARM POE registers */ 444 445 #define NT_ARC_V2 0x600 /* ARCv2 accumulator/extra registers */ 445 446 #define NT_VMCOREDD 0x700 /* Vmcore Device Dump Note */ 446 447 #define NT_MIPS_DSP 0x800 /* MIPS DSP ASE registers */
+9
kernel/events/core.c
··· 13358 13358 return &event->attr; 13359 13359 } 13360 13360 13361 + int perf_allow_kernel(struct perf_event_attr *attr) 13362 + { 13363 + if (sysctl_perf_event_paranoid > 1 && !perfmon_capable()) 13364 + return -EACCES; 13365 + 13366 + return security_perf_event_open(attr, PERF_SECURITY_KERNEL); 13367 + } 13368 + EXPORT_SYMBOL_GPL(perf_allow_kernel); 13369 + 13361 13370 /* 13362 13371 * Inherit an event from parent task to child task. 13363 13372 *
+14
tools/testing/selftests/arm64/abi/hwcap.c
··· 156 156 asm volatile(".inst 0x0ee0e000" : : : ); 157 157 } 158 158 159 + static void poe_sigill(void) 160 + { 161 + /* mrs x0, POR_EL0 */ 162 + asm volatile("mrs x0, S3_3_C10_C2_4" : : : "x0"); 163 + } 164 + 159 165 static void rng_sigill(void) 160 166 { 161 167 asm volatile("mrs x0, S3_3_C2_C4_0" : : : "x0"); ··· 606 600 .hwcap_bit = HWCAP_PMULL, 607 601 .cpuinfo = "pmull", 608 602 .sigill_fn = pmull_sigill, 603 + }, 604 + { 605 + .name = "POE", 606 + .at_hwcap = AT_HWCAP2, 607 + .hwcap_bit = HWCAP2_POE, 608 + .cpuinfo = "poe", 609 + .sigill_fn = poe_sigill, 610 + .sigill_reliable = true, 609 611 }, 610 612 { 611 613 .name = "RNG",
+2 -2
tools/testing/selftests/arm64/abi/ptrace.c
··· 163 163 static int do_child(void) 164 164 { 165 165 if (ptrace(PTRACE_TRACEME, -1, NULL, NULL)) 166 - ksft_exit_fail_msg("PTRACE_TRACEME", strerror(errno)); 166 + ksft_exit_fail_perror("PTRACE_TRACEME"); 167 167 168 168 if (raise(SIGSTOP)) 169 - ksft_exit_fail_msg("raise(SIGSTOP)", strerror(errno)); 169 + ksft_exit_fail_perror("raise(SIGSTOP)"); 170 170 171 171 return EXIT_SUCCESS; 172 172 }
+1
tools/testing/selftests/arm64/signal/.gitignore
··· 2 2 mangle_* 3 3 fake_sigreturn_* 4 4 fpmr_* 5 + poe_* 5 6 sme_* 6 7 ssve_* 7 8 sve_*
+1 -1
tools/testing/selftests/arm64/signal/Makefile
··· 23 23 # Common test-unit targets to build common-layout test-cases executables 24 24 # Needs secondary expansion to properly include the testcase c-file in pre-reqs 25 25 COMMON_SOURCES := test_signals.c test_signals_utils.c testcases/testcases.c \ 26 - signals.S 26 + signals.S sve_helpers.c 27 27 COMMON_HEADERS := test_signals.h test_signals_utils.h testcases/testcases.h 28 28 29 29 .SECONDEXPANSION:
+56
tools/testing/selftests/arm64/signal/sve_helpers.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2024 ARM Limited 4 + * 5 + * Common helper functions for SVE and SME functionality. 6 + */ 7 + 8 + #include <stdbool.h> 9 + #include <kselftest.h> 10 + #include <asm/sigcontext.h> 11 + #include <sys/prctl.h> 12 + 13 + unsigned int vls[SVE_VQ_MAX]; 14 + unsigned int nvls; 15 + 16 + int sve_fill_vls(bool use_sme, int min_vls) 17 + { 18 + int vq, vl; 19 + int pr_set_vl = use_sme ? PR_SME_SET_VL : PR_SVE_SET_VL; 20 + int len_mask = use_sme ? PR_SME_VL_LEN_MASK : PR_SVE_VL_LEN_MASK; 21 + 22 + /* 23 + * Enumerate up to SVE_VQ_MAX vector lengths 24 + */ 25 + for (vq = SVE_VQ_MAX; vq > 0; --vq) { 26 + vl = prctl(pr_set_vl, vq * 16); 27 + if (vl == -1) 28 + return KSFT_FAIL; 29 + 30 + vl &= len_mask; 31 + 32 + /* 33 + * Unlike SVE, SME does not require the minimum vector length 34 + * to be implemented, or the VLs to be consecutive, so any call 35 + * to the prctl might return the single implemented VL, which 36 + * might be larger than 16. So to avoid this loop never 37 + * terminating, bail out here when we find a higher VL than 38 + * we asked for. 39 + * See the ARM ARM, DDI 0487K.a, B1.4.2: I_QQRNR and I_NWYBP. 40 + */ 41 + if (vq < sve_vq_from_vl(vl)) 42 + break; 43 + 44 + /* Skip missing VLs */ 45 + vq = sve_vq_from_vl(vl); 46 + 47 + vls[nvls++] = vl; 48 + } 49 + 50 + if (nvls < min_vls) { 51 + fprintf(stderr, "Only %d VL supported\n", nvls); 52 + return KSFT_SKIP; 53 + } 54 + 55 + return KSFT_PASS; 56 + }
+21
tools/testing/selftests/arm64/signal/sve_helpers.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2024 ARM Limited 4 + * 5 + * Common helper functions for SVE and SME functionality. 6 + */ 7 + 8 + #ifndef __SVE_HELPERS_H__ 9 + #define __SVE_HELPERS_H__ 10 + 11 + #include <stdbool.h> 12 + 13 + #define VLS_USE_SVE false 14 + #define VLS_USE_SME true 15 + 16 + extern unsigned int vls[]; 17 + extern unsigned int nvls; 18 + 19 + int sve_fill_vls(bool use_sme, int min_vls); 20 + 21 + #endif
+15 -31
tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sme_change_vl.c
··· 6 6 * handler, this is not supported and is expected to segfault. 7 7 */ 8 8 9 + #include <kselftest.h> 9 10 #include <signal.h> 10 11 #include <ucontext.h> 11 12 #include <sys/prctl.h> 12 13 13 14 #include "test_signals_utils.h" 15 + #include "sve_helpers.h" 14 16 #include "testcases.h" 15 17 16 18 struct fake_sigframe sf; 17 - static unsigned int vls[SVE_VQ_MAX]; 18 - unsigned int nvls = 0; 19 19 20 20 static bool sme_get_vls(struct tdescr *td) 21 21 { 22 - int vq, vl; 22 + int res = sve_fill_vls(VLS_USE_SME, 2); 23 23 24 - /* 25 - * Enumerate up to SVE_VQ_MAX vector lengths 26 - */ 27 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 28 - vl = prctl(PR_SVE_SET_VL, vq * 16); 29 - if (vl == -1) 30 - return false; 24 + if (!res) 25 + return true; 31 26 32 - vl &= PR_SME_VL_LEN_MASK; 27 + if (res == KSFT_SKIP) 28 + td->result = KSFT_SKIP; 33 29 34 - /* Skip missing VLs */ 35 - vq = sve_vq_from_vl(vl); 36 - 37 - vls[nvls++] = vl; 38 - } 39 - 40 - /* We need at least two VLs */ 41 - if (nvls < 2) { 42 - fprintf(stderr, "Only %d VL supported\n", nvls); 43 - return false; 44 - } 45 - 46 - return true; 30 + return false; 47 31 } 48 32 49 33 static int fake_sigreturn_ssve_change_vl(struct tdescr *td, ··· 35 51 { 36 52 size_t resv_sz, offset; 37 53 struct _aarch64_ctx *head = GET_SF_RESV_HEAD(sf); 38 - struct sve_context *sve; 54 + struct za_context *za; 39 55 40 56 /* Get a signal context with a SME ZA frame in it */ 41 57 if (!get_current_context(td, &sf.uc, sizeof(sf.uc))) 42 58 return 1; 43 59 44 60 resv_sz = GET_SF_RESV_SIZE(sf); 45 - head = get_header(head, SVE_MAGIC, resv_sz, &offset); 61 + head = get_header(head, ZA_MAGIC, resv_sz, &offset); 46 62 if (!head) { 47 - fprintf(stderr, "No SVE context\n"); 63 + fprintf(stderr, "No ZA context\n"); 48 64 return 1; 49 65 } 50 66 51 - if (head->size != sizeof(struct sve_context)) { 67 + if (head->size != sizeof(struct za_context)) { 52 68 fprintf(stderr, "Register data present, aborting\n"); 53 69 return 1; 54 70 } 55 71 56 - sve = (struct sve_context *)head; 72 + za = (struct za_context *)head; 57 73 58 74 /* No changes are supported; init left us at minimum VL so go to max */ 59 75 fprintf(stderr, "Attempting to change VL from %d to %d\n", 60 - sve->vl, vls[0]); 61 - sve->vl = vls[0]; 76 + za->vl, vls[0]); 77 + za->vl = vls[0]; 62 78 63 79 fake_sigreturn(&sf, sizeof(sf), 0); 64 80
+6 -24
tools/testing/selftests/arm64/signal/testcases/fake_sigreturn_sve_change_vl.c
··· 12 12 #include <sys/prctl.h> 13 13 14 14 #include "test_signals_utils.h" 15 + #include "sve_helpers.h" 15 16 #include "testcases.h" 16 17 17 18 struct fake_sigframe sf; 18 - static unsigned int vls[SVE_VQ_MAX]; 19 - unsigned int nvls = 0; 20 19 21 20 static bool sve_get_vls(struct tdescr *td) 22 21 { 23 - int vq, vl; 22 + int res = sve_fill_vls(VLS_USE_SVE, 2); 24 23 25 - /* 26 - * Enumerate up to SVE_VQ_MAX vector lengths 27 - */ 28 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 29 - vl = prctl(PR_SVE_SET_VL, vq * 16); 30 - if (vl == -1) 31 - return false; 24 + if (!res) 25 + return true; 32 26 33 - vl &= PR_SVE_VL_LEN_MASK; 34 - 35 - /* Skip missing VLs */ 36 - vq = sve_vq_from_vl(vl); 37 - 38 - vls[nvls++] = vl; 39 - } 40 - 41 - /* We need at least two VLs */ 42 - if (nvls < 2) { 43 - fprintf(stderr, "Only %d VL supported\n", nvls); 27 + if (res == KSFT_SKIP) 44 28 td->result = KSFT_SKIP; 45 - return false; 46 - } 47 29 48 - return true; 30 + return false; 49 31 } 50 32 51 33 static int fake_sigreturn_sve_change_vl(struct tdescr *td,
+86
tools/testing/selftests/arm64/signal/testcases/poe_siginfo.c
··· 1 + // SPDX-License-Identifier: GPL-2.0 2 + /* 3 + * Copyright (C) 2023 Arm Limited 4 + * 5 + * Verify that the POR_EL0 register context in signal frames is set up as 6 + * expected. 7 + */ 8 + 9 + #include <signal.h> 10 + #include <ucontext.h> 11 + #include <sys/auxv.h> 12 + #include <sys/prctl.h> 13 + #include <unistd.h> 14 + #include <asm/sigcontext.h> 15 + 16 + #include "test_signals_utils.h" 17 + #include "testcases.h" 18 + 19 + static union { 20 + ucontext_t uc; 21 + char buf[1024 * 128]; 22 + } context; 23 + 24 + #define SYS_POR_EL0 "S3_3_C10_C2_4" 25 + 26 + static uint64_t get_por_el0(void) 27 + { 28 + uint64_t val; 29 + 30 + asm volatile( 31 + "mrs %0, " SYS_POR_EL0 "\n" 32 + : "=r"(val) 33 + : 34 + : ); 35 + 36 + return val; 37 + } 38 + 39 + int poe_present(struct tdescr *td, siginfo_t *si, ucontext_t *uc) 40 + { 41 + struct _aarch64_ctx *head = GET_BUF_RESV_HEAD(context); 42 + struct poe_context *poe_ctx; 43 + size_t offset; 44 + bool in_sigframe; 45 + bool have_poe; 46 + __u64 orig_poe; 47 + 48 + have_poe = getauxval(AT_HWCAP2) & HWCAP2_POE; 49 + if (have_poe) 50 + orig_poe = get_por_el0(); 51 + 52 + if (!get_current_context(td, &context.uc, sizeof(context))) 53 + return 1; 54 + 55 + poe_ctx = (struct poe_context *) 56 + get_header(head, POE_MAGIC, td->live_sz, &offset); 57 + 58 + in_sigframe = poe_ctx != NULL; 59 + 60 + fprintf(stderr, "POR_EL0 sigframe %s on system %s POE\n", 61 + in_sigframe ? "present" : "absent", 62 + have_poe ? "with" : "without"); 63 + 64 + td->pass = (in_sigframe == have_poe); 65 + 66 + /* 67 + * Check that the value we read back was the one present at 68 + * the time that the signal was triggered. 69 + */ 70 + if (have_poe && poe_ctx) { 71 + if (poe_ctx->por_el0 != orig_poe) { 72 + fprintf(stderr, "POR_EL0 in frame is %llx, was %llx\n", 73 + poe_ctx->por_el0, orig_poe); 74 + td->pass = false; 75 + } 76 + } 77 + 78 + return 0; 79 + } 80 + 81 + struct tdescr tde = { 82 + .name = "POR_EL0", 83 + .descr = "Validate that POR_EL0 is present as expected", 84 + .timeout = 3, 85 + .run = poe_present, 86 + };
+8 -28
tools/testing/selftests/arm64/signal/testcases/ssve_regs.c
··· 6 6 * set up as expected. 7 7 */ 8 8 9 + #include <kselftest.h> 9 10 #include <signal.h> 10 11 #include <ucontext.h> 11 12 #include <sys/prctl.h> 12 13 13 14 #include "test_signals_utils.h" 15 + #include "sve_helpers.h" 14 16 #include "testcases.h" 15 17 16 18 static union { 17 19 ucontext_t uc; 18 20 char buf[1024 * 64]; 19 21 } context; 20 - static unsigned int vls[SVE_VQ_MAX]; 21 - unsigned int nvls = 0; 22 22 23 23 static bool sme_get_vls(struct tdescr *td) 24 24 { 25 - int vq, vl; 25 + int res = sve_fill_vls(VLS_USE_SME, 1); 26 26 27 - /* 28 - * Enumerate up to SVE_VQ_MAX vector lengths 29 - */ 30 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 31 - vl = prctl(PR_SME_SET_VL, vq * 16); 32 - if (vl == -1) 33 - return false; 27 + if (!res) 28 + return true; 34 29 35 - vl &= PR_SME_VL_LEN_MASK; 30 + if (res == KSFT_SKIP) 31 + td->result = KSFT_SKIP; 36 32 37 - /* Did we find the lowest supported VL? */ 38 - if (vq < sve_vq_from_vl(vl)) 39 - break; 40 - 41 - /* Skip missing VLs */ 42 - vq = sve_vq_from_vl(vl); 43 - 44 - vls[nvls++] = vl; 45 - } 46 - 47 - /* We need at least one VL */ 48 - if (nvls < 1) { 49 - fprintf(stderr, "Only %d VL supported\n", nvls); 50 - return false; 51 - } 52 - 53 - return true; 33 + return false; 54 34 } 55 35 56 36 static void setup_ssve_regs(void)
+8 -28
tools/testing/selftests/arm64/signal/testcases/ssve_za_regs.c
··· 6 6 * signal frames is set up as expected when enabled simultaneously. 7 7 */ 8 8 9 + #include <kselftest.h> 9 10 #include <signal.h> 10 11 #include <ucontext.h> 11 12 #include <sys/prctl.h> 12 13 13 14 #include "test_signals_utils.h" 15 + #include "sve_helpers.h" 14 16 #include "testcases.h" 15 17 16 18 static union { 17 19 ucontext_t uc; 18 20 char buf[1024 * 128]; 19 21 } context; 20 - static unsigned int vls[SVE_VQ_MAX]; 21 - unsigned int nvls = 0; 22 22 23 23 static bool sme_get_vls(struct tdescr *td) 24 24 { 25 - int vq, vl; 25 + int res = sve_fill_vls(VLS_USE_SME, 1); 26 26 27 - /* 28 - * Enumerate up to SVE_VQ_MAX vector lengths 29 - */ 30 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 31 - vl = prctl(PR_SME_SET_VL, vq * 16); 32 - if (vl == -1) 33 - return false; 27 + if (!res) 28 + return true; 34 29 35 - vl &= PR_SME_VL_LEN_MASK; 30 + if (res == KSFT_SKIP) 31 + td->result = KSFT_SKIP; 36 32 37 - /* Did we find the lowest supported VL? */ 38 - if (vq < sve_vq_from_vl(vl)) 39 - break; 40 - 41 - /* Skip missing VLs */ 42 - vq = sve_vq_from_vl(vl); 43 - 44 - vls[nvls++] = vl; 45 - } 46 - 47 - /* We need at least one VL */ 48 - if (nvls < 1) { 49 - fprintf(stderr, "Only %d VL supported\n", nvls); 50 - return false; 51 - } 52 - 53 - return true; 33 + return false; 54 34 } 55 35 56 36 static void setup_regs(void)
+8 -24
tools/testing/selftests/arm64/signal/testcases/sve_regs.c
··· 6 6 * expected. 7 7 */ 8 8 9 + #include <kselftest.h> 9 10 #include <signal.h> 10 11 #include <ucontext.h> 11 12 #include <sys/prctl.h> 12 13 13 14 #include "test_signals_utils.h" 15 + #include "sve_helpers.h" 14 16 #include "testcases.h" 15 17 16 18 static union { 17 19 ucontext_t uc; 18 20 char buf[1024 * 64]; 19 21 } context; 20 - static unsigned int vls[SVE_VQ_MAX]; 21 - unsigned int nvls = 0; 22 22 23 23 static bool sve_get_vls(struct tdescr *td) 24 24 { 25 - int vq, vl; 25 + int res = sve_fill_vls(VLS_USE_SVE, 1); 26 26 27 - /* 28 - * Enumerate up to SVE_VQ_MAX vector lengths 29 - */ 30 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 31 - vl = prctl(PR_SVE_SET_VL, vq * 16); 32 - if (vl == -1) 33 - return false; 27 + if (!res) 28 + return true; 34 29 35 - vl &= PR_SVE_VL_LEN_MASK; 30 + if (res == KSFT_SKIP) 31 + td->result = KSFT_SKIP; 36 32 37 - /* Skip missing VLs */ 38 - vq = sve_vq_from_vl(vl); 39 - 40 - vls[nvls++] = vl; 41 - } 42 - 43 - /* We need at least one VL */ 44 - if (nvls < 1) { 45 - fprintf(stderr, "Only %d VL supported\n", nvls); 46 - return false; 47 - } 48 - 49 - return true; 33 + return false; 50 34 } 51 35 52 36 static void setup_sve_regs(void)
+4 -23
tools/testing/selftests/arm64/signal/testcases/testcases.c
··· 6 6 7 7 #include "testcases.h" 8 8 9 - struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic, 10 - size_t resv_sz, size_t *offset) 11 - { 12 - size_t offs = 0; 13 - struct _aarch64_ctx *found = NULL; 14 - 15 - if (!head || resv_sz < HDR_SZ) 16 - return found; 17 - 18 - while (offs <= resv_sz - HDR_SZ && 19 - head->magic != magic && head->magic) { 20 - offs += head->size; 21 - head = GET_RESV_NEXT_HEAD(head); 22 - } 23 - if (head->magic == magic) { 24 - found = head; 25 - if (offset) 26 - *offset = offs; 27 - } 28 - 29 - return found; 30 - } 31 - 32 9 bool validate_extra_context(struct extra_context *extra, char **err, 33 10 void **extra_data, size_t *extra_size) 34 11 { ··· 160 183 case ESR_MAGIC: 161 184 if (head->size != sizeof(struct esr_context)) 162 185 *err = "Bad size for esr_context"; 186 + break; 187 + case POE_MAGIC: 188 + if (head->size != sizeof(struct poe_context)) 189 + *err = "Bad size for poe_context"; 163 190 break; 164 191 case TPIDR2_MAGIC: 165 192 if (head->size != sizeof(struct tpidr2_context))
+26 -2
tools/testing/selftests/arm64/signal/testcases/testcases.h
··· 26 26 #define HDR_SZ \ 27 27 sizeof(struct _aarch64_ctx) 28 28 29 + #define GET_UC_RESV_HEAD(uc) \ 30 + (struct _aarch64_ctx *)(&(uc->uc_mcontext.__reserved)) 31 + 29 32 #define GET_SF_RESV_HEAD(sf) \ 30 33 (struct _aarch64_ctx *)(&(sf).uc.uc_mcontext.__reserved) 31 34 ··· 91 88 92 89 bool validate_reserved(ucontext_t *uc, size_t resv_sz, char **err); 93 90 94 - struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic, 95 - size_t resv_sz, size_t *offset); 91 + static inline struct _aarch64_ctx *get_header(struct _aarch64_ctx *head, uint32_t magic, 92 + size_t resv_sz, size_t *offset) 93 + { 94 + size_t offs = 0; 95 + struct _aarch64_ctx *found = NULL; 96 + 97 + if (!head || resv_sz < HDR_SZ) 98 + return found; 99 + 100 + while (offs <= resv_sz - HDR_SZ && 101 + head->magic != magic && head->magic) { 102 + offs += head->size; 103 + head = GET_RESV_NEXT_HEAD(head); 104 + } 105 + if (head->magic == magic) { 106 + found = head; 107 + if (offset) 108 + *offset = offs; 109 + } 110 + 111 + return found; 112 + } 113 + 96 114 97 115 static inline struct _aarch64_ctx *get_terminator(struct _aarch64_ctx *head, 98 116 size_t resv_sz,
+8 -24
tools/testing/selftests/arm64/signal/testcases/za_no_regs.c
··· 6 6 * expected. 7 7 */ 8 8 9 + #include <kselftest.h> 9 10 #include <signal.h> 10 11 #include <ucontext.h> 11 12 #include <sys/prctl.h> 12 13 13 14 #include "test_signals_utils.h" 15 + #include "sve_helpers.h" 14 16 #include "testcases.h" 15 17 16 18 static union { 17 19 ucontext_t uc; 18 20 char buf[1024 * 128]; 19 21 } context; 20 - static unsigned int vls[SVE_VQ_MAX]; 21 - unsigned int nvls = 0; 22 22 23 23 static bool sme_get_vls(struct tdescr *td) 24 24 { 25 - int vq, vl; 25 + int res = sve_fill_vls(VLS_USE_SME, 1); 26 26 27 - /* 28 - * Enumerate up to SME_VQ_MAX vector lengths 29 - */ 30 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 31 - vl = prctl(PR_SME_SET_VL, vq * 16); 32 - if (vl == -1) 33 - return false; 27 + if (!res) 28 + return true; 34 29 35 - vl &= PR_SME_VL_LEN_MASK; 30 + if (res == KSFT_SKIP) 31 + td->result = KSFT_SKIP; 36 32 37 - /* Skip missing VLs */ 38 - vq = sve_vq_from_vl(vl); 39 - 40 - vls[nvls++] = vl; 41 - } 42 - 43 - /* We need at least one VL */ 44 - if (nvls < 1) { 45 - fprintf(stderr, "Only %d VL supported\n", nvls); 46 - return false; 47 - } 48 - 49 - return true; 33 + return false; 50 34 } 51 35 52 36 static int do_one_sme_vl(struct tdescr *td, siginfo_t *si, ucontext_t *uc,
+8 -28
tools/testing/selftests/arm64/signal/testcases/za_regs.c
··· 6 6 * expected. 7 7 */ 8 8 9 + #include <kselftest.h> 9 10 #include <signal.h> 10 11 #include <ucontext.h> 11 12 #include <sys/prctl.h> 12 13 13 14 #include "test_signals_utils.h" 15 + #include "sve_helpers.h" 14 16 #include "testcases.h" 15 17 16 18 static union { 17 19 ucontext_t uc; 18 20 char buf[1024 * 128]; 19 21 } context; 20 - static unsigned int vls[SVE_VQ_MAX]; 21 - unsigned int nvls = 0; 22 22 23 23 static bool sme_get_vls(struct tdescr *td) 24 24 { 25 - int vq, vl; 25 + int res = sve_fill_vls(VLS_USE_SME, 1); 26 26 27 - /* 28 - * Enumerate up to SME_VQ_MAX vector lengths 29 - */ 30 - for (vq = SVE_VQ_MAX; vq > 0; --vq) { 31 - vl = prctl(PR_SME_SET_VL, vq * 16); 32 - if (vl == -1) 33 - return false; 27 + if (!res) 28 + return true; 34 29 35 - vl &= PR_SME_VL_LEN_MASK; 30 + if (res == KSFT_SKIP) 31 + td->result = KSFT_SKIP; 36 32 37 - /* Did we find the lowest supported VL? */ 38 - if (vq < sve_vq_from_vl(vl)) 39 - break; 40 - 41 - /* Skip missing VLs */ 42 - vq = sve_vq_from_vl(vl); 43 - 44 - vls[nvls++] = vl; 45 - } 46 - 47 - /* We need at least one VL */ 48 - if (nvls < 1) { 49 - fprintf(stderr, "Only %d VL supported\n", nvls); 50 - return false; 51 - } 52 - 53 - return true; 33 + return false; 54 34 } 55 35 56 36 static void setup_za_regs(void)
+14
tools/testing/selftests/kvm/aarch64/get-reg-list.c
··· 40 40 ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */ 41 41 8, 42 42 1 43 + }, 44 + { 45 + ARM64_SYS_REG(3, 0, 10, 2, 4), /* POR_EL1 */ 46 + ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */ 47 + 16, 48 + 1 49 + }, 50 + { 51 + ARM64_SYS_REG(3, 3, 10, 2, 4), /* POR_EL0 */ 52 + ARM64_SYS_REG(3, 0, 0, 7, 3), /* ID_AA64MMFR3_EL1 */ 53 + 16, 54 + 1 43 55 } 44 56 }; 45 57 ··· 480 468 ARM64_SYS_REG(3, 0, 10, 2, 0), /* MAIR_EL1 */ 481 469 ARM64_SYS_REG(3, 0, 10, 2, 2), /* PIRE0_EL1 */ 482 470 ARM64_SYS_REG(3, 0, 10, 2, 3), /* PIR_EL1 */ 471 + ARM64_SYS_REG(3, 0, 10, 2, 4), /* POR_EL1 */ 483 472 ARM64_SYS_REG(3, 0, 10, 3, 0), /* AMAIR_EL1 */ 484 473 ARM64_SYS_REG(3, 0, 12, 0, 0), /* VBAR_EL1 */ 485 474 ARM64_SYS_REG(3, 0, 12, 1, 1), /* DISR_EL1 */ ··· 488 475 ARM64_SYS_REG(3, 0, 13, 0, 4), /* TPIDR_EL1 */ 489 476 ARM64_SYS_REG(3, 0, 14, 1, 0), /* CNTKCTL_EL1 */ 490 477 ARM64_SYS_REG(3, 2, 0, 0, 0), /* CSSELR_EL1 */ 478 + ARM64_SYS_REG(3, 3, 10, 2, 4), /* POR_EL0 */ 491 479 ARM64_SYS_REG(3, 3, 13, 0, 2), /* TPIDR_EL0 */ 492 480 ARM64_SYS_REG(3, 3, 13, 0, 3), /* TPIDRRO_EL0 */ 493 481 ARM64_SYS_REG(3, 3, 14, 0, 1), /* CNTPCT_EL0 */
+1 -1
tools/testing/selftests/mm/Makefile
··· 106 106 endif 107 107 else 108 108 109 - ifneq (,$(findstring $(ARCH),powerpc)) 109 + ifneq (,$(filter $(ARCH),arm64 powerpc)) 110 110 TEST_GEN_FILES += protection_keys 111 111 endif 112 112
+139
tools/testing/selftests/mm/pkey-arm64.h
··· 1 + /* SPDX-License-Identifier: GPL-2.0 */ 2 + /* 3 + * Copyright (C) 2023 Arm Ltd. 4 + */ 5 + 6 + #ifndef _PKEYS_ARM64_H 7 + #define _PKEYS_ARM64_H 8 + 9 + #include "vm_util.h" 10 + /* for signal frame parsing */ 11 + #include "../arm64/signal/testcases/testcases.h" 12 + 13 + #ifndef SYS_mprotect_key 14 + # define SYS_mprotect_key 288 15 + #endif 16 + #ifndef SYS_pkey_alloc 17 + # define SYS_pkey_alloc 289 18 + # define SYS_pkey_free 290 19 + #endif 20 + #define MCONTEXT_IP(mc) mc.pc 21 + #define MCONTEXT_TRAPNO(mc) -1 22 + 23 + #define PKEY_MASK 0xf 24 + 25 + #define POE_NONE 0x0 26 + #define POE_X 0x2 27 + #define POE_RX 0x3 28 + #define POE_RWX 0x7 29 + 30 + #define NR_PKEYS 8 31 + #define NR_RESERVED_PKEYS 1 /* pkey-0 */ 32 + 33 + #define PKEY_ALLOW_ALL 0x77777777 34 + 35 + #define PKEY_BITS_PER_PKEY 4 36 + #define PAGE_SIZE sysconf(_SC_PAGESIZE) 37 + #undef HPAGE_SIZE 38 + #define HPAGE_SIZE default_huge_page_size() 39 + 40 + /* 4-byte instructions * 16384 = 64K page */ 41 + #define __page_o_noops() asm(".rept 16384 ; nop; .endr") 42 + 43 + static inline u64 __read_pkey_reg(void) 44 + { 45 + u64 pkey_reg = 0; 46 + 47 + // POR_EL0 48 + asm volatile("mrs %0, S3_3_c10_c2_4" : "=r" (pkey_reg)); 49 + 50 + return pkey_reg; 51 + } 52 + 53 + static inline void __write_pkey_reg(u64 pkey_reg) 54 + { 55 + u64 por = pkey_reg; 56 + 57 + dprintf4("%s() changing %016llx to %016llx\n", 58 + __func__, __read_pkey_reg(), pkey_reg); 59 + 60 + // POR_EL0 61 + asm volatile("msr S3_3_c10_c2_4, %0\nisb" :: "r" (por) :); 62 + 63 + dprintf4("%s() pkey register after changing %016llx to %016llx\n", 64 + __func__, __read_pkey_reg(), pkey_reg); 65 + } 66 + 67 + static inline int cpu_has_pkeys(void) 68 + { 69 + /* No simple way to determine this */ 70 + return 1; 71 + } 72 + 73 + static inline u32 pkey_bit_position(int pkey) 74 + { 75 + return pkey * PKEY_BITS_PER_PKEY; 76 + } 77 + 78 + static inline int get_arch_reserved_keys(void) 79 + { 80 + return NR_RESERVED_PKEYS; 81 + } 82 + 83 + void expect_fault_on_read_execonly_key(void *p1, int pkey) 84 + { 85 + } 86 + 87 + void *malloc_pkey_with_mprotect_subpage(long size, int prot, u16 pkey) 88 + { 89 + return PTR_ERR_ENOTSUP; 90 + } 91 + 92 + #define set_pkey_bits set_pkey_bits 93 + static inline u64 set_pkey_bits(u64 reg, int pkey, u64 flags) 94 + { 95 + u32 shift = pkey_bit_position(pkey); 96 + u64 new_val = POE_RWX; 97 + 98 + /* mask out bits from pkey in old value */ 99 + reg &= ~((u64)PKEY_MASK << shift); 100 + 101 + if (flags & PKEY_DISABLE_ACCESS) 102 + new_val = POE_X; 103 + else if (flags & PKEY_DISABLE_WRITE) 104 + new_val = POE_RX; 105 + 106 + /* OR in new bits for pkey */ 107 + reg |= new_val << shift; 108 + 109 + return reg; 110 + } 111 + 112 + #define get_pkey_bits get_pkey_bits 113 + static inline u64 get_pkey_bits(u64 reg, int pkey) 114 + { 115 + u32 shift = pkey_bit_position(pkey); 116 + /* 117 + * shift down the relevant bits to the lowest four, then 118 + * mask off all the other higher bits 119 + */ 120 + u32 perm = (reg >> shift) & PKEY_MASK; 121 + 122 + if (perm == POE_X) 123 + return PKEY_DISABLE_ACCESS; 124 + if (perm == POE_RX) 125 + return PKEY_DISABLE_WRITE; 126 + return 0; 127 + } 128 + 129 + static void aarch64_write_signal_pkey(ucontext_t *uctxt, u64 pkey) 130 + { 131 + struct _aarch64_ctx *ctx = GET_UC_RESV_HEAD(uctxt); 132 + struct poe_context *poe_ctx = 133 + (struct poe_context *) get_header(ctx, POE_MAGIC, 134 + sizeof(uctxt->uc_mcontext), NULL); 135 + if (poe_ctx) 136 + poe_ctx->por_el0 = pkey; 137 + } 138 + 139 + #endif /* _PKEYS_ARM64_H */
+8
tools/testing/selftests/mm/pkey-helpers.h
··· 91 91 #include "pkey-x86.h" 92 92 #elif defined(__powerpc64__) /* arch */ 93 93 #include "pkey-powerpc.h" 94 + #elif defined(__aarch64__) /* arch */ 95 + #include "pkey-arm64.h" 94 96 #else /* arch */ 95 97 #error Architecture not supported 96 98 #endif /* arch */ 97 99 100 + #ifndef PKEY_MASK 98 101 #define PKEY_MASK (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE) 102 + #endif 99 103 104 + #ifndef set_pkey_bits 100 105 static inline u64 set_pkey_bits(u64 reg, int pkey, u64 flags) 101 106 { 102 107 u32 shift = pkey_bit_position(pkey); ··· 111 106 reg |= (flags & PKEY_MASK) << shift; 112 107 return reg; 113 108 } 109 + #endif 114 110 111 + #ifndef get_pkey_bits 115 112 static inline u64 get_pkey_bits(u64 reg, int pkey) 116 113 { 117 114 u32 shift = pkey_bit_position(pkey); ··· 123 116 */ 124 117 return ((reg >> shift) & PKEY_MASK); 125 118 } 119 + #endif 126 120 127 121 extern u64 shadow_pkey_reg; 128 122
+3
tools/testing/selftests/mm/pkey-powerpc.h
··· 8 8 # define SYS_pkey_free 385 9 9 #endif 10 10 #define REG_IP_IDX PT_NIP 11 + #define MCONTEXT_IP(mc) mc.gp_regs[REG_IP_IDX] 12 + #define MCONTEXT_TRAPNO(mc) mc.gp_regs[REG_TRAPNO] 11 13 #define REG_TRAPNO PT_TRAP 14 + #define MCONTEXT_FPREGS 12 15 #define gregs gp_regs 13 16 #define fpregs fp_regs 14 17 #define si_pkey_offset 0x20
+4
tools/testing/selftests/mm/pkey-x86.h
··· 15 15 16 16 #endif 17 17 18 + #define MCONTEXT_IP(mc) mc.gregs[REG_IP_IDX] 19 + #define MCONTEXT_TRAPNO(mc) mc.gregs[REG_TRAPNO] 20 + #define MCONTEXT_FPREGS 21 + 18 22 #ifndef PKEY_DISABLE_ACCESS 19 23 # define PKEY_DISABLE_ACCESS 0x1 20 24 #endif
+98 -11
tools/testing/selftests/mm/protection_keys.c
··· 147 147 * will then fault, which makes sure that the fault code handles 148 148 * execute-only memory properly. 149 149 */ 150 - #ifdef __powerpc64__ 150 + #if defined(__powerpc64__) || defined(__aarch64__) 151 151 /* This way, both 4K and 64K alignment are maintained */ 152 152 __attribute__((__aligned__(65536))) 153 153 #else ··· 212 212 unsigned long syscall_flags = 0; 213 213 int ret; 214 214 int pkey_rights; 215 - u64 orig_pkey_reg = read_pkey_reg(); 216 215 217 216 dprintf1("START->%s(%d, 0x%x)\n", __func__, 218 217 pkey, flags); ··· 241 242 242 243 dprintf1("%s(%d) pkey_reg: 0x%016llx\n", 243 244 __func__, pkey, read_pkey_reg()); 244 - if (flags) 245 - pkey_assert(read_pkey_reg() >= orig_pkey_reg); 246 245 dprintf1("END<---%s(%d, 0x%x)\n", __func__, 247 246 pkey, flags); 248 247 } ··· 250 253 unsigned long syscall_flags = 0; 251 254 int ret; 252 255 int pkey_rights = hw_pkey_get(pkey, syscall_flags); 253 - u64 orig_pkey_reg = read_pkey_reg(); 254 256 255 257 pkey_assert(flags & (PKEY_DISABLE_ACCESS | PKEY_DISABLE_WRITE)); 256 258 ··· 269 273 270 274 dprintf1("%s(%d) pkey_reg: 0x%016llx\n", __func__, 271 275 pkey, read_pkey_reg()); 272 - if (flags) 273 - assert(read_pkey_reg() <= orig_pkey_reg); 274 276 } 275 277 276 278 void pkey_write_allow(int pkey) ··· 308 314 ucontext_t *uctxt = vucontext; 309 315 int trapno; 310 316 unsigned long ip; 317 + #ifdef MCONTEXT_FPREGS 311 318 char *fpregs; 319 + #endif 312 320 #if defined(__i386__) || defined(__x86_64__) /* arch */ 313 321 u32 *pkey_reg_ptr; 314 322 int pkey_reg_offset; ··· 324 328 __func__, __LINE__, 325 329 __read_pkey_reg(), shadow_pkey_reg); 326 330 327 - trapno = uctxt->uc_mcontext.gregs[REG_TRAPNO]; 328 - ip = uctxt->uc_mcontext.gregs[REG_IP_IDX]; 331 + trapno = MCONTEXT_TRAPNO(uctxt->uc_mcontext); 332 + ip = MCONTEXT_IP(uctxt->uc_mcontext); 333 + #ifdef MCONTEXT_FPREGS 329 334 fpregs = (char *) uctxt->uc_mcontext.fpregs; 335 + #endif 330 336 331 337 dprintf2("%s() trapno: %d ip: 0x%016lx info->si_code: %s/%d\n", 332 338 __func__, trapno, ip, si_code_str(si->si_code), ··· 357 359 #endif /* arch */ 358 360 359 361 dprintf1("siginfo: %p\n", si); 362 + #ifdef MCONTEXT_FPREGS 360 363 dprintf1(" fpregs: %p\n", fpregs); 364 + #endif 361 365 362 366 if ((si->si_code == SEGV_MAPERR) || 363 367 (si->si_code == SEGV_ACCERR) || ··· 389 389 #elif defined(__powerpc64__) /* arch */ 390 390 /* restore access and let the faulting instruction continue */ 391 391 pkey_access_allow(siginfo_pkey); 392 + #elif defined(__aarch64__) 393 + aarch64_write_signal_pkey(uctxt, PKEY_ALLOW_ALL); 392 394 #endif /* arch */ 393 395 pkey_faults++; 394 396 dprintf1("<<<<==================================================\n"); ··· 904 902 * test program continue. We now have to restore it. 905 903 */ 906 904 if (__read_pkey_reg() != 0) 907 - #else /* arch */ 905 + #elif defined(__aarch64__) 906 + if (__read_pkey_reg() != PKEY_ALLOW_ALL) 907 + #else 908 908 if (__read_pkey_reg() != shadow_pkey_reg) 909 909 #endif /* arch */ 910 910 pkey_assert(0); ··· 1496 1492 lots_o_noops_around_write(&scratch); 1497 1493 do_not_expect_pkey_fault("executing on PROT_EXEC memory"); 1498 1494 expect_fault_on_read_execonly_key(p1, pkey); 1495 + 1496 + // Reset back to PROT_EXEC | PROT_READ for architectures that support 1497 + // non-PKEY execute-only permissions. 1498 + ret = mprotect_pkey(p1, PAGE_SIZE, PROT_EXEC | PROT_READ, (u64)pkey); 1499 + pkey_assert(!ret); 1499 1500 } 1500 1501 1501 1502 void test_implicit_mprotect_exec_only_memory(int *ptr, u16 pkey) ··· 1674 1665 } 1675 1666 #endif 1676 1667 1668 + #if defined(__aarch64__) 1669 + void test_ptrace_modifies_pkru(int *ptr, u16 pkey) 1670 + { 1671 + pid_t child; 1672 + int status, ret; 1673 + struct iovec iov; 1674 + u64 trace_pkey; 1675 + /* Just a random pkey value.. */ 1676 + u64 new_pkey = (POE_X << PKEY_BITS_PER_PKEY * 2) | 1677 + (POE_NONE << PKEY_BITS_PER_PKEY) | 1678 + POE_RWX; 1679 + 1680 + child = fork(); 1681 + pkey_assert(child >= 0); 1682 + dprintf3("[%d] fork() ret: %d\n", getpid(), child); 1683 + if (!child) { 1684 + ptrace(PTRACE_TRACEME, 0, 0, 0); 1685 + 1686 + /* Stop and allow the tracer to modify PKRU directly */ 1687 + raise(SIGSTOP); 1688 + 1689 + /* 1690 + * need __read_pkey_reg() version so we do not do shadow_pkey_reg 1691 + * checking 1692 + */ 1693 + if (__read_pkey_reg() != new_pkey) 1694 + exit(1); 1695 + 1696 + raise(SIGSTOP); 1697 + 1698 + exit(0); 1699 + } 1700 + 1701 + pkey_assert(child == waitpid(child, &status, 0)); 1702 + dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status); 1703 + pkey_assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP); 1704 + 1705 + iov.iov_base = &trace_pkey; 1706 + iov.iov_len = 8; 1707 + ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_ARM_POE, &iov); 1708 + pkey_assert(ret == 0); 1709 + pkey_assert(trace_pkey == read_pkey_reg()); 1710 + 1711 + trace_pkey = new_pkey; 1712 + 1713 + ret = ptrace(PTRACE_SETREGSET, child, (void *)NT_ARM_POE, &iov); 1714 + pkey_assert(ret == 0); 1715 + 1716 + /* Test that the modification is visible in ptrace before any execution */ 1717 + memset(&trace_pkey, 0, sizeof(trace_pkey)); 1718 + ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_ARM_POE, &iov); 1719 + pkey_assert(ret == 0); 1720 + pkey_assert(trace_pkey == new_pkey); 1721 + 1722 + /* Execute the tracee */ 1723 + ret = ptrace(PTRACE_CONT, child, 0, 0); 1724 + pkey_assert(ret == 0); 1725 + 1726 + /* Test that the tracee saw the PKRU value change */ 1727 + pkey_assert(child == waitpid(child, &status, 0)); 1728 + dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status); 1729 + pkey_assert(WIFSTOPPED(status) && WSTOPSIG(status) == SIGSTOP); 1730 + 1731 + /* Test that the modification is visible in ptrace after execution */ 1732 + memset(&trace_pkey, 0, sizeof(trace_pkey)); 1733 + ret = ptrace(PTRACE_GETREGSET, child, (void *)NT_ARM_POE, &iov); 1734 + pkey_assert(ret == 0); 1735 + pkey_assert(trace_pkey == new_pkey); 1736 + 1737 + ret = ptrace(PTRACE_CONT, child, 0, 0); 1738 + pkey_assert(ret == 0); 1739 + pkey_assert(child == waitpid(child, &status, 0)); 1740 + dprintf3("[%d] waitpid(%d) status: %x\n", getpid(), child, status); 1741 + pkey_assert(WIFEXITED(status)); 1742 + pkey_assert(WEXITSTATUS(status) == 0); 1743 + } 1744 + #endif 1745 + 1677 1746 void test_mprotect_pkey_on_unsupported_cpu(int *ptr, u16 pkey) 1678 1747 { 1679 1748 int size = PAGE_SIZE; ··· 1787 1700 test_pkey_syscalls_bad_args, 1788 1701 test_pkey_alloc_exhaust, 1789 1702 test_pkey_alloc_free_attach_pkey0, 1790 - #if defined(__i386__) || defined(__x86_64__) 1703 + #if defined(__i386__) || defined(__x86_64__) || defined(__aarch64__) 1791 1704 test_ptrace_modifies_pkru, 1792 1705 #endif 1793 1706 };