.. | .. |
---|
242 | 242 | mte_check_tfsr_el1(); |
---|
243 | 243 | } |
---|
244 | 244 | |
---|
| 245 | +void mte_cpu_setup(void) |
---|
| 246 | +{ |
---|
| 247 | + u64 rgsr; |
---|
| 248 | + |
---|
| 249 | + /* |
---|
| 250 | + * CnP must be enabled only after the MAIR_EL1 register has been set |
---|
| 251 | + * up. Inconsistent MAIR_EL1 between CPUs sharing the same TLB may |
---|
| 252 | + * lead to the wrong memory type being used for a brief window during |
---|
| 253 | + * CPU power-up. |
---|
| 254 | + * |
---|
| 255 | + * CnP is not a boot feature so MTE gets enabled before CnP, but let's |
---|
| 256 | + * make sure that is the case. |
---|
| 257 | + */ |
---|
| 258 | + BUG_ON(read_sysreg(ttbr0_el1) & TTBR_CNP_BIT); |
---|
| 259 | + BUG_ON(read_sysreg(ttbr1_el1) & TTBR_CNP_BIT); |
---|
| 260 | + |
---|
| 261 | + /* Normal Tagged memory type at the corresponding MAIR index */ |
---|
| 262 | + sysreg_clear_set(mair_el1, |
---|
| 263 | + MAIR_ATTRIDX(MAIR_ATTR_MASK, MT_NORMAL_TAGGED), |
---|
| 264 | + MAIR_ATTRIDX(MAIR_ATTR_NORMAL_TAGGED, |
---|
| 265 | + MT_NORMAL_TAGGED)); |
---|
| 266 | + |
---|
| 267 | + write_sysreg_s(KERNEL_GCR_EL1, SYS_GCR_EL1); |
---|
| 268 | + |
---|
| 269 | + /* |
---|
| 270 | + * If GCR_EL1.RRND=1 is implemented the same way as RRND=0, then |
---|
| 271 | + * RGSR_EL1.SEED must be non-zero for IRG to produce |
---|
| 272 | + * pseudorandom numbers. As RGSR_EL1 is UNKNOWN out of reset, we |
---|
| 273 | + * must initialize it. |
---|
| 274 | + */ |
---|
| 275 | + rgsr = (read_sysreg(CNTVCT_EL0) & SYS_RGSR_EL1_SEED_MASK) << |
---|
| 276 | + SYS_RGSR_EL1_SEED_SHIFT; |
---|
| 277 | + if (rgsr == 0) |
---|
| 278 | + rgsr = 1 << SYS_RGSR_EL1_SEED_SHIFT; |
---|
| 279 | + write_sysreg_s(rgsr, SYS_RGSR_EL1); |
---|
| 280 | + |
---|
| 281 | + /* clear any pending tag check faults in TFSR*_EL1 */ |
---|
| 282 | + write_sysreg_s(0, SYS_TFSR_EL1); |
---|
| 283 | + write_sysreg_s(0, SYS_TFSRE0_EL1); |
---|
| 284 | + |
---|
| 285 | + local_flush_tlb_all(); |
---|
| 286 | +} |
---|
| 287 | + |
---|
245 | 288 | void mte_suspend_enter(void) |
---|
246 | 289 | { |
---|
247 | 290 | if (!system_supports_mte()) |
---|
.. | .. |
---|
258 | 301 | mte_check_tfsr_el1(); |
---|
259 | 302 | } |
---|
260 | 303 | |
---|
| 304 | +void mte_suspend_exit(void) |
---|
| 305 | +{ |
---|
| 306 | + if (!system_supports_mte()) |
---|
| 307 | + return; |
---|
| 308 | + |
---|
| 309 | + mte_cpu_setup(); |
---|
| 310 | +} |
---|
| 311 | + |
---|
261 | 312 | long set_mte_ctrl(struct task_struct *task, unsigned long arg) |
---|
262 | 313 | { |
---|
263 | 314 | u64 mte_ctrl = (~((arg & PR_MTE_TAG_MASK) >> PR_MTE_TAG_SHIFT) & |
---|