| .. | .. |
|---|
| 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) & |
|---|