|
1091 | 1091 | __emit_inst(0xd5000000|(\sreg)|(.L__gpr_num_\rt)) |
1092 | 1092 | .endm |
1093 | 1093 |
|
| 1094 | + .macro msr_hcr_el2, reg |
| 1095 | +#if IS_ENABLED(CONFIG_AMPERE_ERRATUM_AC04_CPU_23) |
| 1096 | + dsb nsh |
| 1097 | + msr hcr_el2, \reg |
| 1098 | + isb |
| 1099 | +#else |
| 1100 | + msr hcr_el2, \reg |
| 1101 | +#endif |
| 1102 | + .endm |
1094 | 1103 | #else |
1095 | 1104 |
|
1096 | 1105 | #include <linux/bitfield.h> |
|
1178 | 1187 | write_sysreg(__scs_new, sysreg); \ |
1179 | 1188 | } while (0) |
1180 | 1189 |
|
| 1190 | +#define sysreg_clear_set_hcr(clear, set) do { \ |
| 1191 | + u64 __scs_val = read_sysreg(hcr_el2); \ |
| 1192 | + u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set); \ |
| 1193 | + if (__scs_new != __scs_val) \ |
| 1194 | + write_sysreg_hcr(__scs_new); \ |
| 1195 | +} while (0) |
| 1196 | + |
1181 | 1197 | #define sysreg_clear_set_s(sysreg, clear, set) do { \ |
1182 | 1198 | u64 __scs_val = read_sysreg_s(sysreg); \ |
1183 | 1199 | u64 __scs_new = (__scs_val & ~(u64)(clear)) | (set); \ |
1184 | 1200 | if (__scs_new != __scs_val) \ |
1185 | 1201 | write_sysreg_s(__scs_new, sysreg); \ |
1186 | 1202 | } while (0) |
1187 | 1203 |
|
| 1204 | +#define write_sysreg_hcr(__val) do { \ |
| 1205 | + if (IS_ENABLED(CONFIG_AMPERE_ERRATUM_AC04_CPU_23) && \ |
| 1206 | + (!system_capabilities_finalized() || \ |
| 1207 | + alternative_has_cap_unlikely(ARM64_WORKAROUND_AMPERE_AC04_CPU_23))) \ |
| 1208 | + asm volatile("dsb nsh; msr hcr_el2, %x0; isb" \ |
| 1209 | + : : "rZ" (__val)); \ |
| 1210 | + else \ |
| 1211 | + asm volatile("msr hcr_el2, %x0" \ |
| 1212 | + : : "rZ" (__val)); \ |
| 1213 | +} while (0) |
| 1214 | + |
1188 | 1215 | #define read_sysreg_par() ({ \ |
1189 | 1216 | u64 par; \ |
1190 | 1217 | asm(ALTERNATIVE("nop", "dmb sy", ARM64_WORKAROUND_1508412)); \ |
|
0 commit comments